Saya memiliki skrip bash yang membangun baris perintah dalam string berdasarkan pada beberapa parameter sebelum menjalankannya dalam sekali jalan. Bagian-bagian yang digabungkan ke string perintah seharusnya dipisahkan oleh pipa untuk memfasilitasi "streaming" data melalui masing-masing komponen.
Contoh yang sangat sederhana:
#!/bin/bash
part1=gzip -c
part2=some_other_command
cmd="cat infile"
if [ ! "$part1" = "" ]
then
cmd+=" | $part1"
fi
if [ ! "$part2" = "" ]
then
cmd+=" | $part2"
fi
cmd+="> outfile"
#show command. It looks ok
echo $cmd
#run the command. fails with pipes
$cmd
Untuk beberapa alasan, pipa-pipa itu sepertinya tidak berfungsi. Ketika saya menjalankan skrip ini saya mendapatkan pesan kesalahan yang berbeda yang biasanya berkaitan dengan bagian pertama dari perintah (sebelum pipa pertama).
Jadi pertanyaan saya adalah apakah mungkin untuk membangun perintah dengan cara ini, dan apa cara terbaik untuk melakukannya?
infile
ada di direktori saat ini?Jawaban:
Itu semua tergantung pada saat hal-hal dievaluasi. Saat Anda mengetik
$cmd
, seluruh baris lainnya dilewatkan sebagai argumen untuk kata pertama di$cmd
.Ini menunjukkan bahwa argumen yang diteruskan ke
echo
perintah adalah: "/etc/passwd
", "|
" (karakter bilah vertikal), "wc
" dan "-l
".Dari
man bash
:sumber
Salah satu solusi untuk ini, untuk referensi di masa mendatang, adalah menggunakan "eval". Ini memastikan bahwa apa pun cara string ditafsirkan oleh bash dilupakan dan semuanya dibaca seolah-olah itu diketik langsung di shell (yang persis seperti yang kita inginkan).
Jadi pada contoh di atas, gantikan
dengan
memecahkannya.
sumber
eval foo "a b"
akan sama denganeval foo "a" "b"
.@waltinator sudah menjelaskan mengapa ini tidak berfungsi seperti yang Anda harapkan. Cara lain untuk menggunakannya adalah
bash -c
dengan menjalankan perintah Anda:sumber
bash -c
, tetapi gunakaneval
untuk melakukan perintah dalam proses saat ini.Mungkin cara yang lebih baik untuk melakukan ini adalah untuk menghindari menggunakan
eval
dan hanya menggunakan array Bash dan itu perluasan inline untuk membangun semua argumen dan kemudian jalankan melawan perintah.sumber