ฉันพยายามแก้ปัญหาที่แตกต่างกันเป็นทรัพยากรที่ดีรวมทั้งข้อมูลพื้นฐานและทางเลือกสำหรับตัวอย่าง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) - ปล่อยใหม่)