Apakah satu-satunya opsi untuk perluasan perintah bash:
- tanda kutip
$(..)
yang outputnya selalu diuraikan dengan pemisahan string dumb, atau - dikutip
"$(..)"
output siapa yang selalu diteruskan sebagai satu unit?
Saya mencoba meniru di bash fungsi shell ikan yang saya buat untuk digunakan di Mac OS. Fungsi ikan saya selection
https://superuser.com/a/1165855 mengambil pilihan di jendela paling depan dan menampilkan jalur untuk digunakan dalam substitusi perintah seperti ls -l (selection)
. Saya berharap dapat mencapai hal yang sama di bash mungkin sebagai ls -l $(selection)
.
Saya pikir itu adalah masalah mengutip dan jadi mencoba melewati jalur linefeed-delimited ke bash's printf "%q "
. Namun saya menemukan bahwa tidak peduli apa pun kutipan yang saya masukkan output substitusi perintah, itu terbagi di spasi putih.
Contoh sederhana:
$ touch file\ a file\ b
$ ls $( echo "file\ a file\ b" ) # want expansion equiv to: ls 'file a' 'file b'
ls: a: No such file or directory
ls: b: No such file or directory
ls: file\: No such file or directory
ls: file\: No such file or directory
Itu tidak akan menjadi akhir dari dunia jika saya harus menggunakan substitusi perintah yang dikutip seperti ls -l "$(selection)"
tetapi melakukan bahwa output perintah tidak pernah terpecah, tidak pernah memperhatikan pengamatan saya yang cermat. Apakah sintaks backtick yang lama berbeda?
Lucu, bash, Anda punya banyak fitur. Apakah tidak ada yang mengizinkan cmda $(cmdb-that-generates-parameters-for-cmda)
? Atau apakah pengguna bash menghindari spasi atau simbol dalam nama file (seperti binatang) untuk membuat semuanya mudah? Terima kasih atas jawaban apa pun.
sumber
;
karaktercmda $(cmdb-that-generates-parameters-for-cmda)
, contoh yang lebih harfiah:transcode $(selection)
. Sepertinya tidak mungkin, saya akan mulai menggunakan shell ikan di Mac pekerjaan saya.Dengan
xargs
:Pikirkan kutipannya. Note
xargs
bukan Bash bawaan (saya sebutkan ini dalam konteks "Bash, Anda punya banyak fitur").Dengan
eval
yang merupakan Bash builtin:Sekali lagi, perhatikan kutipannya. Ini bisa menjadi bumerang dengan mudah . Metode yang didasarkan pada perubahan
IFS
( jawaban lain ini ) tampaknya lebih aman. Di sisi laineval
Anda bahkan dapat melakukan ini:Sayangnya tidak ada yang sesederhana
ls (selection)
sintaksis shell lain yang Anda mulai. Namun Anda dapat menyederhanakan sintaksis dari setiap solusi (?) Dengan fungsi kustom, misalnya:Ini memungkinkan Anda untuk menelepon
_ ls selection
, jika hanyaselection
menghasilkan input yangxargs
benar. Lebih baik lagi, ini:membuat
_ ls -l "file c" selection
mungkin. Saya kira Anda dapat membuat fungsi serupa yang menggunakan metode "ubahIFS
" dari jawaban lain.Namun, ini tidak sefleksibel dan seanggun ikan
ls (selection)
. Saya berharap Anda bisa melakukannyals (selection1) (selection2)
pada ikan;_
fungsi di atas tidak mencakup kasus ini.Di sisi lain
eval ls $(selection1) $(selection2)
dapat bekerja jikaselection1
danselection2
mengembalikan string yang disanitasi dengan kutipan dan / atau melarikan diri yang tepat. Jika penyerang dapat membuat Anda memilih file bernama; rm -rf ~/;
Anda sebaiknya membersihkan dengan baik; atau tidak digunakaneval
di tempat pertama.sumber
eval
.