Bir bash betiği yazarken && eşdeğeri nedir?


31

Bu yinelenen bir soru ise şimdiden özür dilerim. Buraya sormadan önce araştırmak / kontrol etmek için çaba sarf ettim.

Böyle bir gömlek yazarken rahatım:

foocommand && foocommand2 && foocommand3

Fikir, önceki komutun "başarılı" olması durumunda yalnızca sonraki komutların çalıştırılmasını istediğimdir.

Biraz uzun bir senaryo yazıyorum ve bu tek gömlek mümkün değil çünkü herkes için büyük bir kafa karıştırıcı kod bloğuna benziyor.

Komutları boşluk bırakmak ve aralarında yorum yazabilmek istiyorum. Bunu nasıl yapabilirim ve hala içinde && eşdeğeri var mı?


4
Bu ayılar tekrar: &&Önceki eğer müteakip komutu çalıştırmak anlamına gelmez bir başarılı oldu. Bu eğer komut çalıştırmak anlamına gelir kolektif sonuç ait tüm komuta listedeki önceki komutları başarıdır. Bunu biliyor olabilirsiniz, ancak gelecekteki okuyucular yanlış anlayabilir.
kojiro

1
Ayrıca sadece bir not olarak, tanımladığınız bu davranışa, kendisinden geldiği ||ve &&( |veya aksine &) kısa devre olduğu söylenir. Son operatörlerle kullanılan davranışa istekli değerlendirme denir.
AndyPerfect,

7
@kojiro: Ayrımı göremiyorum. a && b && cyalnızca başarılı bolursa açalışır, bu nedenle "yalnızca başarılı colursa çalışır b" ve "yalnızca başarılı ve her ikisi de başarılı colursa " eşdeğer ifadelerdir: başarılı olmadıkça başarılı olamaz . abba
Şubat'ta 13:13

1
@ruakh a || b && cdaha açıklayıcıdır.
kojiro

8
@ ruakh hayır, true || false && echo hiçıkacaktır hi. Şartname okur, "&&" ve "||" operatörleri eşit önceliğe sahip olacak ve sol birliktelik ile değerlendirilecektir.
kojiro

Yanıtlar:


23

Böyle yapabilirsiniz:

#!/bin/sh
ls -lh &&
    # This is a comment
    echo 'Wicked, it works!'

Umarım ne istediğini doğru anlamışımdır.


Teşekkürler. Bu, yapmayı umduğum en yakın şeydi. Gerekirse tek bir astar haline dönüşmeyi çok kolaylaştırır.
Mike B

Mike, kod temizliği konusunda endişe duyduğunuzdan, ortak bir kural, zincirin 2-N bölümlerini birinci bölümün girintisi yapmaktır.
abblaine

@jblaine Ne demek istediğini anladığımdan emin değilim. Lütfen detaylandırır mısın?
Mike B

Mike, Stackexchange cevabımı doğru bir şekilde biçimlendirmeme izin vermiyor, bu yüzden demek istediğim
şudur

@jblaine İyi nokta, çizgileri girintilemek için düzenlendi.
Volker Siegel

38

Shebang hattını değiştirebilirsin.

#!/bin/bash -e

Herhangi bir hatadan sonra komut dosyası duracaktır.


1
İlginç. Aklımda tutarım. Teşekkür ederim.
Mike B

ihtiyacım olduğunda set -e
yazmamdan

@Silverrocker POSIX de ( bashelbette ki bölüm hariç ). POSIX kabuğu, uygulanabilir olan birçok seçeneğe sahiptir set. Ya da tam tersi? setkomut dosyasında kabuk komut satırı seçeneklerini ayarlama yöntemidir.
Kaz

7
Ne yazık ki, normal çıkış durumu kurallarını takip etmeyen birtakım standart yardımcı programlar vardır, bu yüzden -eyanlış davranabilirler. Örneğin, muhtemelen diffiki özdeş olmayan dosya her zaman komut dosyanızın sonlandırılmasını istemezsiniz . Elbette, bu tür komutları ekleyerek || true(veya belki de || [ $? = 1 ]) ekleyerek bu sorunu çözebilirsiniz, ancak OP, bu senaryoyu okumak zorunda kalacak bir "herkes" ten bahseder ve "herkes" de büyük olasılıkla kullanmaya alışmaz başa çıkmak -e.
Şubat'ta 13:23

4
Ben koymak için kullanılan -eŞirketim bir yönetici ile benim komut başlatılması tuttu kadar o-patlamayla ilgili bash myscript.shgöz ardı böylece, -e. Şimdi bütün senaryolarım set -eikinci sırada.
Carlos Campderrós

19

set -eFikri beğenmediyseniz , belki mantığı tersine çevirebilirsiniz.

foocommand || exit 1
foocommand2 || exit 2
foocommand3 || exit 3

Daha faydalı, exityararlı bir hata mesajı yazdırmak için bir şeyle değiştirin , ardından çıkın. Bir işlevin içinde, elbette returnyerine exit.


11
Veya foocommand || exitile çıkmak için foocommandsıfırdan eğer bireyin çıkış durumu.
Stéphane Chazelas

Bu nasıl çalışıyor? C'deki gibi - sol argüman DOĞRU olarak değerlendirirse, artık argümanlar kontrol edilmez mi?
Vorac

Evet bu doğru. Lisp'te (ve genel olarak işlevsel diller, sanırım) ve Perl'de yaygın bir deyimdir.
üçlü

9

Bunun if else fiyerine blokları kullanabilirsiniz .

if foocommand; then

  # some comments

  if foocommand2; then

    # more comments

    foocommand3
  fi
fi

Biraz daha okunaklı.

Alternatif olarak sadece \1 büyük astarınızı birkaç satıra ayırmak için kullanabilirsiniz .

foocommand && \
  # some comment
  foocommand2 && \
    # more comment
    foocommand3

Fakat elbette bu eğitimsiz gözle karıştırılabilir.


4
\Orada gerekli olduğunu sanmıyorum .
Samuel Edwin Ward

Haklısın. Alışkanlık gücü.
Martín Canaval

5

İç içe ififadeler kullanmayı düşünebilirsiniz . Diğer seçenek ise, kıvırcık grubu kullanmak gibi{ true && echo hi; } || echo huh

Güncelleme 1:

İşte yeni satırlar / yorumlar olmadan bir örnek:

{ { false && echo "inner true"; } && { echo "inner true" && true; } || { echo "inner false" && false; } || echo "outter false"; }

@Stephane Noktalı virgül eklediğiniz için teşekkür ederiz. Telefonumu cevaplamak için kullanıyorum, bu yüzden cevaplarımı iki kez kontrol etmedim. :)
livingstaccato

İlginç fikir. Evet, ifadeler iç içe geçmeyi düşünmüştüm, ancak birlikte çok fazla şey zincirlerseniz, karışıklığa neden olabilir.
Mike B

4

Her komut dizisini işlevlere ayırın:

big_block_1() {
  # ...
}
big_block_2() {
  # ...
}
big_block_3() {
  # ...
}

big_block_1 && big_block_2 && big_block_3

0

Her zaman, hata oluştuğunda yapacağım şeyi belirtmeme izin veren ve sonra ||deseni kullanmama izin veren bir "başarısız" işlevini yazmayı seviyorum . Aşağıdaki gibi:

function fail() {
  echo "Failure: ${@}"
  exit 1
}

foocommand || fail "couldn't foo"
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.