Apakah ada cara untuk menulis ulang struktur perintah A && B || C | D
sehingga 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 | D
sehingga 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 || C
akan disalurkan ke D
.
sh
:)
A
ada 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 B
atau C
, tetapi A && B || C
tidak mencapai itu. Jika A
berhasil, tetapi B
berjalan dan gagal, itu akan dijalankan C
.
Catatan 1: jika Anda entah bagaimana dapat menjamin bahwa B
selalu 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 A
tidak 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 bash
dan pgrep bash | cat
dan if true; then pgrep bash; fi
dan { pgrep bash; }
memiliki satu garis keluaran; ( pgrep bash; )
dan ( pgrep bash; ) | cat
dan { pgrep bash; } | cat
dan if true; then pgrep bash; fi | cat
memiliki 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 A
sebagai input D
. Untuk mencapai itu, Anda memerlukan pengalihan aliran A
tergantung pada kebutuhan Anda.
Jika Anda ingin membuang output A
:
{ A >/dev/null && B || C; } | D
Jika Anda ingin melihat output A
pada terminal:
{ A >/dev/tty && B || C; } | D
Jika Anda membutuhkan output A
sebagai input dari perintah selanjutnya E
Anda akan memerlukan grup perintah tambahan dan pengalihan aliran:
{ { A >&3 && B || C; } | D; } 3>&1 | E
Jika semua ini terlihat terlalu misterius bagi Anda (seperti halnya bagi saya), saya sarankan Anda menggunakan variabel shell khusus untuk status keluar A
dan 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.)
A
dari saluran pipa.
A && (B || C) | D
, jika Anda tidak ingin B, C, atau D berjalan ketika A gagal