Saya memiliki aplikasi yang mengambil atribut input dalam tanda kutip ganda yang tertanam dalam tanda kutip tunggal. Ambil contoh perintah yang benar ini:
command -p 'cluster="cl1"'
Untuk mengotomatiskannya, saya membuat file bash menggunakan $CLUSTER
sebagai variabel. Bagaimana seharusnya perintah saya? Dengan kata lain, apa yang harus saya letakkan bukannya cl1?
Harap dicatat bahwa, Jika saya mengubah perintah di atas, itu tidak akan diterima. Misalnya: command -p "cluster=cl1"
tidak diterima
CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"
cli
tanpa tanda kutip di dalamCLUSTER
variabel):CLUSTER='cl1'; command -p 'cluster="'"$CLUSTER"'"'
Jawaban:
Sepertinya perintah Anda mungkin mengatur variabel lingkungan berdasarkan argumen yang diberikan pada baris perintah. Mungkin bisa Anda lakukan:
... dan atur lingkungannya untuk itu saat doa.
Kalau tidak, kutipan shell biasanya membatasi argumen atau keluar dari karakter shell khusus lainnya dari interpretasi shell. Anda dapat memuat (dan karenanya melarikan diri) berbagai jenis kutipan-shell di dalam jenis-jenis lain berdasarkan berbagai aturan:
"''''"
- string yang dikutip lembut dapat berisi sejumlah kutipan keras."\""
-\
backslash dapat lolos dari"
soft-quote dalam"
string yang dikutip lembut.\\
backslash juga lolos sendiri,\$
token ekspansi, dan\n
garis seperti yang disebutkan di bawah, tetapi sebaliknya diperlakukan secara harfiah."${expand} and then some"
- string yang dikutip lembut dapat berisi$
ekspansi shell yang ditafsirkan .'"\'
-'
string yang dikutip keras dapat berisi karakter apa pun selain'
kutipan keras.\
- backslash yang tidak dikutip akan lolos dari karakter berikut untuk interpretasi literal - bahkan backslash yang lain - kecuali\n
ewline.\\n
kasus ewline baik\
backslash dan\n
ewline sepenuhnya dihapus dari perintah yang ditafsirkan yang dihasilkan.${parameter+expand "$parameter"}
- kutipan yang dihasilkan dari ekspansi shell hampir tidak pernah berfungsi sebagai penanda pembatas kecuali beberapa kasus khusus. Saya tidak akan berani menjelaskan lebih lanjut di sini.Saya menganggapnya aneh bahwa aplikasi apa pun akan menginterpretasikan tanda kutip dalam baris perintahnya. Praktek semacam itu tidak masuk akal dalam hal itu - setidaknya untuk kerang - tujuan utama dari kutipan umumnya untuk membatasi argumen. Namun demikian, pada saat doa, argumen selalu sudah dibatasi dengan
\0NUL
karakter dan oleh karena itu kutipan tidak dapat melayani banyak tujuan.Bahkan shell biasanya hanya akan repot untuk menafsirkan kutipan dalam salah satu argumen doa ketika dipanggil dengan
-c
switch - yang menunjukkan bahwa operan pertamanya sebenarnya adalah skrip shell yang harus dijalankan pada permintaan. Ini adalah kasus input dua kali dievaluasi .Semua yang dikatakan, Anda dapat melakukan sejumlah hal untuk melewati kutipan literal melalui argumen di baris perintah. Sebagai contoh:
Seperti yang saya catat dalam komentar sebelumnya, Anda bisa memuat
"
kutipan dalam ekspansi yang"
dikutip sendiri .Anda dapat melarikan diri
"
dengan\
backslash dalam"
string yang dikutip.Anda dapat mengganti dan menggabungkan gaya kutipan untuk sampai pada hasil akhir yang Anda inginkan sebagai catatan @jimmij di atas .
Anda dapat menonaktifkan pembuatan dan
$IFS
pemisahan nama file - dengan demikian menghindari keharusan mengutip$expansion
sama sekali - sehingga hanya mengutip kutipan. Ini mungkin berlebihan.Terakhir, ada jenis lain dari kutipan-shell yang mungkin digunakan. Seperti yang saya catat sebelumnya,
sh -c "$scriptlet"
bentuk doa shell sering digunakan untuk menyediakan skrip shell pada command-line. Namun ketika$scriptlet
menjadi rumit - seperti ketika kutipan harus mengandung kutipan lain - sering kali menguntungkan jika menggunakan dokumen di sini dansh -s
sebagai gantinya - di mana shell secara khusus diinstruksikan untuk menetapkan semua operan berikut ke parameter posisi seperti yang akan dilakukan dalam suatu-c
kasus dan belum juga mengambil skripnya daristdin
.Jika perintah Anda harus menginterpretasikan tanda kutip dengan cara ini maka saya akan menganggapnya lebih baik jika bisa melakukannya dalam input file. Sebagai contoh:
Jika Anda tidak mengutip pembatas a
<<here-document
maka semua isinya diperlakukan hampir persis seperti yang"
dikutip lembut - kecuali bahwa"
tanda kutip ganda sendiri tidak diperlakukan secara khusus. Jadi jika kita menjalankan hal di atas dengancat
:... itu mencetak ...
sumber
Seperti mikeserv menulis:
"Double quote" setiap literal yang berisi spasi / metakarakter dan setiap ekspansi:
"$var"
,"$(command "$var")"
,"${array[@]}"
,"a & b"
. Gunakan'single quotes'
untuk kode atau literal$'s: 'Costs $5 US'
,ssh host 'echo "$HOSTNAME"'
. Lihathttp://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words
sumber
"
karakter - hanya yang pertama dan terakhir yang cukup. Masalah sebenarnya di sini adalah aplikasi Anda menafsirkan kutipan dalam sebuah argumen. Menafsirkan kutipan dalam argumen hampir tidak pernah merupakan ide yang baik karena kutipan seharusnya hanya menjadi sarana untuk membatasi argumen - dan pada doa bahwa pembatasan ditangani oleh\0NUL
s dalam setiap kasus. Mungkin ada cara yang lebih baik untuk meneruskan informasi yang Anda inginkan ke aplikasi? Sukacommand --'script=/path/to/some/file'
atau apalah?