Boru B'den D'ye mi? - A && B || C | D


14

Komut yapısını yeniden yazmak için bir yol var mı A && B || C | D?

Geçerli komutla ya sadece B ya da hem C hem de D çalıştırılır.

Örneğin:

resim açıklamasını buraya girin

Yanıtlar:


31

Evet, bash'de parantez kullanabilirsiniz:

(A && B || C) | D

Bu şekilde çıktısı A && B || Cboruya geçirilecektir D.


6
Veya A && (B || C) | DA başarısız olduğunda B, C veya D'nin çalışmasını istemiyorsanız
zwol

2
Ayrıca parens kullanabilirsiniz sh:)
EKons

Kıvırcık parantez yerine parantez kullanmanın kasıtlı bir karar (eğer öyleyse faydaları nelerdir?) Veya sadece bir gözetim olup olmadığı belirsizdir. Açıklayabilir misiniz?
Tom Fenech

@TomFenech Parens, ifadenin, komut dosyasının geri kalanının POV'sinden (tek) ayrı bir işlem olan bir alt kabukta çalışmasına neden olur. Bu nedenle, ifadenin parens içindeki çıktısı ne olursa olsun, birlikte pipetlenecektir. ( AA
Alt

1
@jpaugh Bence izolasyon hakkında iyi bir noktaya sahip ama kıvırcık parantez kullanırken çıktı aynı şekilde boru olurdu, değil mi?
Tom Fenech

14

Bunu şu şekilde yazabilirsiniz:

if A; then B; else C; fi | D

Sen de koşmak istediğini söylüyorsun ya Bda C, ama A && B || Cbunu başaramadı. EğerA , ancak başarılı Bkoşular ve başarısız, bu çalıştıracaktır C.

Not 1: bir şekilde garanti ederseniz B Her zaman başarılı olduğunu ve kısa bir versiyona sadık kalmak istiyorsanız bir yine de tercih ederim

{ A && B || C; } | D

üzerinde ( ... )veya uzak optimize almak olmayabilir yeni altkabuk oluşturulacak ikincisi gereksiz yere kuvvetler gibi.

Not 2: Her iki formda da Aörnekte doğru olmayan ancak genel olarak böyle bir çıktı bulunmadığı varsayılır . Bundan kaçınılabilir

A; if [ "$?" -eq 0 ]; then B; else C; fi | D

{ … }Boru nedeniyle bir alt kabuğun oluşturulmasına zorlamadığından emin misiniz ? Aşağıdaki davranış dikkat edin: pgrep bashve pgrep bash | catve if true; then pgrep bash; five { pgrep bash; }çıkışın bir satır var; ( pgrep bash; )ve ( pgrep bash; ) | catve { pgrep bash; } | catve if true; then pgrep bash; fi | catiki çıkış hattı var.
wchargin

@wchargin ... | ...bir alt kabuğun oluşturulmasına neden olur, bu kaçınılmazdır. ( ... ), en azından teoride, kaçınan ek bir alt kabuğun yaratılmasına neden olur { ...; }, ancak "optimize edilebilir veya optimize edilemez" ile kastettiğim budur: bu özel durumda, kabuğun önemli olmadığını fark etmesi mümkündür, etkisi aynı olurdu.
Hvd

5

Alıcı yanıtı doğrudur, ancak girişinin çıktısı olmayan potansiyel kullanım durumunu kapsamaz . Bunu başarmak için ihtiyaçlarınıza bağlı olarak bir akış yönlendirmesi yapmanız gerekir.ADA

  • AYine de çıktıyı silmek istiyorsanız :

    { A >/dev/null && B || C; } | D
  • ATerminaldeki çıkışını görmek istiyorsanız :

    { A >/dev/tty && B || C; } | D
  • ABir sonraki komutun girdisi olarak çıktısına Eihtiyacınız varsa, ek bir komut grubuna ve akış yönlendirmesine ihtiyacınız olacaktır:

    { { A >&3 && B || C; } | D; } 3>&1 | E

Tüm bunlar size çok gizemli görünüyorsa (bana olduğu gibi) çıkış durumu için özel kabuk değişkenini kullanmanızı ve bununla çalışmanızı öneririm A:

A
if [ $? -eq 0 ]; then
  B
else
  C
fi |
D

Daha özlü olmak, ancak çok gizemli olmak istemiyorsanız, bunu öneririm:

A; { [ $? -eq 0 ] && B || C; } | D

(Ayrıca orijinal cevabımı yazdığımda fark etmediğim hvd cevabının son bölümüne de bakınız .)


Cevabım bunu kapsıyor. Sadece not aldığım "Not 2:" 'a ne koyduğumu görünABoru hattının dışına .
Hvd

@hvd: Haklısın ve cevabının bu kısmını bana gösterdiğin için teşekkürler! Talebimi değiştirdim ve buna göre kredi verdim.
David Foerster
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.