Tanda kutip dihapus sebelum argumen diteruskan ke skrip Anda, jadi sudah terlambat untuk mempertahankannya. Yang dapat Anda lakukan adalah mempertahankan efeknya saat meneruskan argumen ke perintah dalam, dan merekonstruksi versi argumen yang dikutip/diloloskan yang setara untuk dicetak.
Untuk meneruskan argumen ke perintah dalam "[email protected]"
-- dengan tanda kutip ganda, [email protected] mempertahankan jeda kata aslinya, yang berarti bahwa perintah dalam menerima daftar argumen yang persis sama seperti yang dilakukan skrip Anda.
Untuk pencetakan, Anda dapat menggunakan format %q dalam perintah printf bash untuk merekonstruksi kutipan. Perhatikan bahwa ini tidak selalu merekonstruksi kutipan asli, tetapi akan membuat setara string yang dikutip/diloloskan. Misalnya, jika Anda meneruskan argumen 'uptime ; uname -a'
mungkin mencetak uptime\ \;\ uname\ -a
atau "uptime ; uname -a"
atau yang setara lainnya (lihat jawaban @William Pursell untuk contoh serupa).
Berikut ini contoh penggunaannya:
printf "Running command:"
printf " %q" innercmd "[email protected]" # note the space before %q -- this inserts spaces between arguments
printf "\n"
innercmd "[email protected]"
Jika pengguna memanggil perintah Anda sebagai:
./script 'foo'
argumen pertama yang diberikan pada skrip adalah string foo
tanpa tanda kutip. Tidak ada cara bagi skrip Anda untuk membedakan antara itu dan metode lain mana pun yang dapat digunakan untuk mendapatkan foo
sebagai argumen (misalnya ./script $(echo foo)
atau ./script foo
atau ./script "foo"
atau ./script \f\o""''""o
).
Jika Anda ingin mencetak daftar argumen sedekat mungkin dengan apa yang mungkin dimasukkan pengguna:
#!/bin/bash
chars='[ !"#$&()*,;<>?\^`{|}]'
for arg
do
if [[ $arg == *\'* ]]
then
arg=\""$arg"\"
elif [[ $arg == *$chars* ]]
then
arg="'$arg'"
fi
allargs+=("$arg") # ${allargs[@]} is to be used only for printing
done
printf '%s\n' "${allargs[*]}"
Itu tidak sempurna. Argumen seperti ''\''"'
lebih sulit untuk diakomodasi daripada yang dibenarkan.