Saya ingin mengulang output dari perintah tanpa membuat sub-shell atau menggunakan file sementara.
Versi awal skrip saya terlihat seperti ini, tetapi ini tidak berfungsi karena ia membuat subkulit, dan exit
perintah mengakhiri subkulit bukan skrip utama yang diperlukan. Ini adalah bagian dari skrip yang lebih besar untuk mengonfigurasi perutean kebijakan, dan menghentikan eksekusi jika mendeteksi suatu kondisi yang akan menyebabkan perutean gagal.
sysctl -a 2>/dev/null | grep '\.rp_filter' | while read -r -a RPSTAT ; do
if [[ "0" != "${RPSTAT[2]}" ]] ; then
echo >&2 "RP Filter must be disabled on all interfaces!"
echo >&2 "The RP filter feature is incompatible with policy routing"
exit 1
fi
done
Jadi salah satu alternatif yang disarankan adalah menggunakan perintah seperti ini untuk menghindari subkulit.
while read BLAH ; do echo $BLAH; done </root/regularfile
Jadi menurut saya saya juga harus dapat menggunakan perintah seperti ini untuk menghindari subshell dan masih mendapatkan output dari program yang saya inginkan.
while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Sayangnya, menggunakan perintah itu menghasilkan kesalahan ini.
-bash: syntax error near unexpected token `<(sysct ...
Saya benar-benar bingung karena ini berhasil.
cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Saya bisa menyimpan output dari perintah itu ke file sementara, dan menggunakan redirect pada file sementara, tetapi saya ingin menghindari melakukan itu.
Jadi mengapa pengalihan memberi saya kesalahan, dan apakah saya memiliki opsi selain membuat file sementara?
sumber
Jawaban:
Anda melewatkan
<
. Seharusnya:Pikirkan
<(sysctl -a 2>/dev/null | grep '\.rp_filter')
sebagai file.sumber
<(
di manual bash (ini berada di bawah "substitusi proses").Untuk beberapa alternatif lagi jika ada yang datang ke sini lagi ...
Bergantung pada shell, Anda mungkin bisa menggunakan
set -o errexit
agar shell induk keluar ketika perintah (termasuk subkulit) keluar tidak nol tanpa terjebak dalamif
blok atau trailing&&
atau||
, seperti dalamAtau, Anda dapat meminta sinyal subshell yang digunakan orang tua untuk membunuh dan variabel lingkungan $ PPID, jika tersedia.
Atau Anda bisa memindahkan blok sementara ke fungsi dan mengembalikan 0/1 (secara eksplisit mengembalikan 0 setelah blok sementara) dan lakukan saja seperti pipa Anda
sysctl | grep | function || exit
. Saya kira Anda bisa meletakkan pengembalian di blok inline juga, tetapi fungsi adalah teman Anda. ;)sumber