Saya mencoba berbagai solusi, sumber yang bagus termasuk informasi latar belakang dan alternatifnya adalah misalnya BashFAQ / 096 di Greg's (alias. GreyCat's) Wiki . Secara keseluruhan saya menemukan dua berikut ini yang paling mudah dibaca (dari yang berfungsi):
Karena Bash 4.4 (sejauh yang saya tahu dari BERITA ) adalah mungkin untuk menggunakan ekspansi parameter @Q
seperti ini:
adb sh -c "other_tool -a -b ${*@Q}"
Perhatikan bahwa saya menggunakan di $*
sini bukan $@
karena Anda ingin "other_tool -a -b ${*@Q}"
menjadi satu string tunggal, bukan satu string per argumen yang diteruskan.
Jika Anda ingin melakukan hal yang sama dengan variabel array bash Anda akan memerlukan sintaks ${ARRAY[*]@Q}
(dalam tanda kutip).
Jika Anda tidak memiliki Bash 4.4 atau yang lebih baru atau tidak yakin, ini adalah solusi pilihan saya:
function escapeBashArgs() {
local arg separator=""
for arg
do
printf "%s%q" "$separator" "$arg"
separator=" "
done
}
adb sh -c "other_tool -a -b $(escapeBashArgs "$@")"
Perhatikan bahwa di sini Anda perlu menggunakan "$@"
alih-alih $@
atau "$*"
atau $*
karena Anda tidak ingin pemisahan kata dalam argumen, sehingga varian tanpa kutip tidak dapat digunakan, dan Anda ingin jumlah argumen dipertahankan, jadi "$*"
tidak dapat digunakan karena akan bergabung semua argumen menjadi string tunggal. Fungsi kemudian mengembalikan semua argumen dalam satu string.
Jika Anda tidak peduli dengan ruang tambahan di depan argumen pertama, Anda dapat mengubah printf
string format ke " %q"
dan menghapus separator
variabel. Atau Anda dapat menggunakan one-liner dari jawaban Gordon Davissons .
Solusi ini bekerja dengan semua kasus yang bisa saya buat, terutama:
- Tidak ada argumen:
escapeBashArgs
→ tidak ada
- Argumen kosong:
escapeBashArgs "" ""
→'' ''
- Argumen dengan hanya spasi:
escapeBashArgs " " " "
→ ' ' ' '
atau \ \ \ \ \
( ruang terakhir dimakan oleh renderer situs ini )
- Argumen dengan spasi khusus dan baris baru:
escapeBashArgs "a b" c\ d "arg with
newline"
→ 'a b' 'c d' $'arg with\nnewline'
atau a\ \ \ \ \ \ b c\ d $'arg with\nnewline'
( baris baru antara with
dan newline
, pada posisi lain karena pembungkus baris di situs ini )
- Argumen dengan karakter khusus:
escapeBashArgs '$"'\''({:})'
→ '$"'\''({:})'
atau\$\"\'\(\{:\}\)
- Contoh dari jawaban jcayzacs :
escapeBashArgs x/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
→ 'x/ "b"/aaaaa/'\''xxx yyyy'\''/zz"offf"'
ataux/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
(Diuji dengan GNU bash 5.0.3 (1) -release.)