Apakah ada cara untuk menulis ulang struktur perintah A && B || C | Dsehingga B atau C disalurkan ke D?
Dengan perintah saat ini, hanya B atau C dan D yang dijalankan.
Sebagai contoh:
Apakah ada cara untuk menulis ulang struktur perintah A && B || C | Dsehingga B atau C disalurkan ke D?
Dengan perintah saat ini, hanya B atau C dan D yang dijalankan.
Sebagai contoh:
Jawaban:
Ya, di bash Anda dapat menggunakan tanda kurung:
(A && B || C) | D
Dengan cara ini, output dari A && B || Cakan disalurkan ke D.
sh:)
Aada di dalam subkulit, ini juga termasuk A.)
Anda dapat menulis ini sebagai
if A; then B; else C; fi | D
Anda mengatakan ingin menjalankan salah satu Batau C, tetapi A && B || Ctidak mencapai itu. Jika Aberhasil, tetapi Bberjalan dan gagal, itu akan dijalankan C.
Catatan 1: jika Anda entah bagaimana dapat menjamin bahwa Bselalu berhasil dan ingin tetap dengan versi pendek, maka saya masih akan memilih
{ A && B || C; } | D
lebih ( ... ), karena yang terakhir tidak perlu memaksa subkulit baru untuk dibuat, yang mungkin atau mungkin tidak dioptimalkan.
Catatan 2: kedua bentuk menganggap Atidak menghasilkan output, yang benar dalam contoh Anda tetapi tidak harus demikian pada umumnya. Itu bisa dihindari dengan
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }tidak memaksa subshell dibuat karena pipa? Saya mengamati perilaku berikut: pgrep bashdan pgrep bash | catdan if true; then pgrep bash; fidan { pgrep bash; }memiliki satu garis keluaran; ( pgrep bash; )dan ( pgrep bash; ) | catdan { pgrep bash; } | catdan if true; then pgrep bash; fi | catmemiliki dua jalur output.
... | ...menyebabkan subkulit dibuat, itu tidak dapat dihindari. ( ... ), setidaknya dalam teori, menyebabkan subkulit tambahan dibuat yang { ...; }menghindari, tapi itulah yang saya maksud dengan "mungkin atau mungkin tidak dioptimalkan": ada kemungkinan bahwa dalam kasus khusus ini, shell menyadari itu tidak masalah, efeknya akan sama.
Jawaban accepter benar tetapi tidak mencakup kasus penggunaan potensial untuk tidak memiliki output Asebagai input D. Untuk mencapai itu, Anda memerlukan pengalihan aliran Atergantung pada kebutuhan Anda.
Jika Anda ingin membuang output A:
{ A >/dev/null && B || C; } | DJika Anda ingin melihat output Apada terminal:
{ A >/dev/tty && B || C; } | DJika Anda membutuhkan output Asebagai input dari perintah selanjutnya EAnda akan memerlukan grup perintah tambahan dan pengalihan aliran:
{ { A >&3 && B || C; } | D; } 3>&1 | EJika semua ini terlihat terlalu misterius bagi Anda (seperti halnya bagi saya), saya sarankan Anda menggunakan variabel shell khusus untuk status keluar Adan bekerja dengan itu:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Jika Anda ingin lebih ringkas tetapi tidak terlalu misterius saya sarankan ini:
A; { [ $? -eq 0 ] && B || C; } | D
(Lihat juga bagian terakhir dari jawaban hvd yang tidak saya perhatikan ketika saya menulis jawaban asli saya.)
Adari saluran pipa.
A && (B || C) | D, jika Anda tidak ingin B, C, atau D berjalan ketika A gagal