Parameter ikan, sebagai aturan, lolos sebelum disuntikkan ke perintah ikan:
mqudsi@freebsd> echo hello > hello\ world.txt
mqudsi@freebsd> file (echo hello world.txt)
hello world.txt: ASCII text
Namun, hasil dari ekspansi kurung kurawal tidak lolos dengan benar, _and_ tidak ada cara mudah untuk lolos untuk menghindarinya secara manual karena memasukkan tanda kutip di sekitar parameter merusak ekspansi:
mqudsi@freebsd> echo -n hello\ {1,2,3}.txt\n
hello 1.txt
hello 2.txt
hello 3.txt
Seperti yang Anda lihat, setelah parameter pertama, echo
dilewatkan dua argumen terpisah hello
dan #.txt
, yang mengarah ke ruang ekstra di depan kata-kata.
Membungkus argumen dalam tanda kutip mengarah ke yang berikut:
mqudsi@freebsd> echo -n "hello\ {1,2,3}.txt\n"
hello\ {1,2,3}.txt\n
Saat mencoba mengatasi masalah dengan memasukkan tanda kutip yang lolos ke dalam string asli (dengan anggapan bahwa isi string tidak diloloskan setelah penggantian dan sebelum injeksi) mengarah ke tanda kutip yang diloloskan dengan benar, mencegah hasil yang diinginkan:
mqudsi@freebsd> echo -n \"hello\ {1,2,3}.txt\n\" "hello 1.txt " "hello 2.txt " "hello 3.txt
"
Sepertinya ekspansi parameter terjadi setelah tahap pemisahan argumen.
echo
sedang diteruskan dua argumen terpisah hello dan #.txt, yang mengarah ke ruang ekstra di depan kata-kata.
Saya tidak setuju dengan diagnosis itu. echo
sedang melewati 3 argumen (masing-masing diakhiri dengan \n
), yang echo
patuh mencetak dengan spasi di antaranya. Saya tidak melihat bug di sini.
Inilah yang saya lakukan untuk men-debug argumen:
~> printf '«%s»' hei\ {1,2,3}.txt\n
«hei 1.txt
»«hei 2.txt
»«hei 3.txt
»⏎
Inilah yang saya lakukan untuk men-debug argumen:
Saya menggunakan string escape
, yaitu
> string escape -- hello\ {1,2,3}.txt\n
hello\ 1.txt\n
hello\ 2.txt\n
hello\ 3.txt\n
yang berarti Anda benar-benar mendapatkan apa yang saya harapkan. Anda mendapatkan argumen lengkap dengan "1", lalu dengan "2" dan kemudian dengan "3". Argumen lengkap kebetulan menyertakan baris baru.
@mqudsi : Saya akan menganggap apa yang membuat Anda
(command)
) pada baris baru. Itu berarti \n
sini tidak memiliki arti khusus setelah diganti dengan karakter baris baru. Ini adalah "karakter", sejauh menyangkut sisanya. Kami tidak perlu _escape_ karakter, kami hanya tidak menjalankan pemisahan.Atau di file (echo hello world.txt)
, "hello world.txt" _tidak_ lolos ke hello\ world.txt
, hanya saja tidak terpecah karena tidak ada baris baru. Jika Anda memiliki file bernama hello\nworld.txt
, ini akan memiliki masalah yang mirip dengan masalah bash dengan spasi.
echo
menyisipkan spasi di antara argumennya (jika "-s" tidak diberikan). Itulah yang menyebabkan lekukan aneh - karena spasi terjadi tepat setelah baris baru.Itu berarti jika Anda ingin memiliki output
hello 1.txt
hello 2.txt
hello 3.txt
gunakan echo -s
atau printf '%s\n' hello\ {1,2,3}.txt
.
Saya percaya ini adalah kesalahpahaman, bukan bug. Apakah saya benar?
Maaf, teman-teman! Saya mencoba membuat repro minimal untuk suatu masalah dan bingung dengan sesuatu yang sama sekali berbeda. Saya mendapatkan perilaku ekspansi parameter yang salah, khususnya, saya bingung dengan perilaku parallel
atau xargs
dengan batas 1, yaitu saya menganggap echo {1,2,3}
akan berkembang menjadi 3 perintah dengan masing-masing 1 argumen dan bukan 1 perintah dengan 3 argumen.
Terima kasih telah meluruskan saya.