ฉันพยายามแก้ปัญหาที่แตกต่างกันเป็นทรัพยากรที่ดีรวมทั้งข้อมูลพื้นฐานและทางเลือกสำหรับตัวอย่างBashFAQ / 096 บนของเกร็ก (aka. GreyCat) ที่วิกิพีเดีย ทั้งหมดฉันพบว่าทั้งสองต่อไปนี้จะอ่านได้มากที่สุด (จากคนที่ทำงาน):
ตั้งแต่ Bash 4.4 (เท่าที่ฉันสามารถบอกได้จากข่าว ) มันเป็นไปได้ที่จะใช้การขยายพารามิเตอร์ @Q
เช่นนี้
adb sh -c "other_tool -a -b ${*@Q}"
โปรดทราบว่าฉันใช้$*
ที่นี่แทน$@
เพราะคุณต้องการที่"other_tool -a -b ${*@Q}"
จะเป็นหนึ่งสายเดียวแทนหนึ่งสายต่อการโต้แย้ง
หากคุณต้องการทำเช่นเดียวกันกับตัวแปรอาร์เรย์ของ bashคุณจะต้องใช้ไวยากรณ์${ARRAY[*]@Q}
(ภายในเครื่องหมายคำพูด)
หากคุณไม่มี Bash 4.4 หรือใหม่กว่าหรือไม่แน่ใจนี่เป็นโซลูชันที่ฉันต้องการ:
function escapeBashArgs() {
local arg separator=""
for arg
do
printf "%s%q" "$separator" "$arg"
separator=" "
done
}
adb sh -c "other_tool -a -b $(escapeBashArgs "$@")"
โปรดทราบว่าที่นี่คุณจำเป็นต้องใช้"$@"
แทน$@
หรือ"$*"
หรือ$*
เพราะคุณไม่ต้องการแยกคำภายในอาร์กิวเมนต์ดังนั้นจึงไม่สามารถใช้ชุดรูปแบบที่ไม่มีการอ้างอิงและคุณต้องการให้หมายเลขของอาร์กิวเมนต์ถูกสงวนไว้ดังนั้นจึง"$*"
ไม่สามารถใช้ร่วมได้ อาร์กิวเมนต์ทั้งหมดเป็นสตริงเดี่ยว ฟังก์ชันจะส่งคืนอาร์กิวเมนต์ทั้งหมดในสตริงเดียว
หากคุณไม่สนใจพื้นที่เพิ่มเติมด้านหน้าอาร์กิวเมนต์แรกคุณสามารถเปลี่ยนprintf
สตริงรูปแบบเป็น" %q"
และลบseparator
ตัวแปรได้ หรือคุณสามารถใช้หนึ่งซับจากคำตอบของกอร์ดอน Davissons
โซลูชันนี้ใช้ได้กับทุกกรณีที่ฉันสามารถทำได้โดยเฉพาะ:
- ไม่มีข้อโต้แย้ง:
escapeBashArgs
→ ไม่มีอะไร
- อาร์กิวเมนต์ว่างเปล่า:
escapeBashArgs "" ""
→'' ''
- อาร์กิวเมนต์ที่มีเพียงช่องว่าง:
escapeBashArgs " " " "
→ ' ' ' '
หรือ\ \ \ \ \
( การแสดงผลช่องว่างสุดท้ายจะถูกแสดงโดยไซต์นี้ )
- อาร์กิวเมนต์ที่มีระยะห่างพิเศษและบรรทัดใหม่:
escapeBashArgs "a b" c\ d "arg with
newline"
→ 'a b' 'c d' $'arg with\nnewline'
หรือa\ \ \ \ \ \ b c\ d $'arg with\nnewline'
( ขึ้นบรรทัดใหม่อยู่ระหว่างwith
และnewline
ในตำแหน่งอื่น ๆ เนื่องจากการตัดบรรทัดบนไซต์นี้ )
- อาร์กิวเมนต์ที่มีอักขระพิเศษ:
escapeBashArgs '$"'\''({:})'
→ '$"'\''({:})'
หรือ\$\"\'\(\{:\}\)
- ตัวอย่างจากคำตอบ jcayzacs :
escapeBashArgs x/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
→ 'x/ "b"/aaaaa/'\''xxx yyyy'\''/zz"offf"'
หรือx/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
(ทดสอบกับ GNU bash 5.0.3 (1) - ปล่อยใหม่)