Bir kabuk komutundaki “&&” nin amacı nedir?


Yanıtlar:


399

&&önceki komutun başarıyla tamamlanıp tamamlanmadığına bağlı olarak bir şey yapmanıza olanak tanır - bu yüzden onu zincirleme olarak görme eğilimindesiniz do_something && do_something_else_that_depended_on_something.


391

Dahası, daha önce komuta ne olduğunu umursamayan, hangisinin ||mantıklı ya da ;sadece bir ayırıcı olduğuna da sahipsiniz .

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Bununla ilgili bazı ayrıntıları burada Bash Manual'daki Komut Listeleri bulabilirsiniz .


5
Belki eklemek istersiniz false && echo "Will not be printed".
MTSan

112

komut satırı - amacı &&nedir?

Kabuğunda, gördüğünüzde

$ command one && command two

amaç, &&yalnızca ilk komut başarılı olduğunda izleyen komutu yürütmektir . Bu Posix mermilerinin deyimidir ve sadece Bash'te bulunmaz.

Birincisi başarısız olursa, ikinci sürecin çalışmasını önlemeyi amaçlamaktadır.

"Niyet" kelimesini kullandığımı fark edebilirsiniz - bu iyi bir nedendir. Tüm programlar aynı davranışa sahip değildir, bu nedenle bunun çalışması için, programın ne "hata" olduğunu düşündüğünü ve belgeleri ve gerekirse kaynak kodunu okuyarak programı nasıl ele aldığını anlamanız gerekir.

Kabuğunuz true için 0, false için diğer pozitif sayılar için bir dönüş değeri olarak kabul eder

Programlar çıkışta bir sinyal döndürür . Başarılı bir şekilde çıkarlarsa 0, yapmazlarsa sıfırdan büyük olmalıdırlar. Bu, işlemler arasında sınırlı miktarda iletişime izin verir.

&&Olarak adlandırılır AND_IFolarak POSIX kabuk dilbilgisi bir parçasıdır, and_orliste de içeren bir komut, ||bir olan OR_IFbenzer semantik ile.

Belgelerden alıntılanan dilbilgisi sembolleri:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

Ve herhangi bir sayıda AND_IFs ( &&) ve / veya OR_IFs ( ||) ' nin ( and_ortekrar tekrar tanımlandığı gibi ) birlikte gerdirilebileceğini gösteren Gramer (belgelerden de alıntılanmıştır ):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Her iki operatör de eşit önceliğe sahiptir ve soldan sağa değerlendirilir (sol ilişkiseldir). Dokümanların dediği gibi:

Bir AND-ORliste operatörleri tarafından ayrılan bir veya daha fazla boru hattı bir dizisidir "&&"ve "||".

Bir listesi bir veya daha fazla bir dizisidir ve-veya listeler operatörler ile ayrılmış ';'ve '&'ve isteğe bağlı olarak sona ';', '&'ya da.

Operatörler "&&"ve "||"eşit önceliğe sahip olmalı ve sol birliktelikle değerlendirilmelidir. Örneğin, aşağıdaki komutların her ikisi de standart çıktıya yalnızca çubuk yazar:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. İlk durumda, false, durumuyla çıkan bir komuttur. 1

    $ false
    $ echo $?
    1

    bu vasıtalar, echo fooçalışmaz (yani, kısa devre echo foo). Sonra komut echo baryürütülür.

  2. İkinci durumda, true kodu 0

    $ true
    $ echo $?
    0

    ve bu nedenle echo fooyürütülmez, sonra echo baryürütülür.


31

'&&' için oldukça yaygın bir kullanım, yazılımı otomatik araçlarla derlemektir. Örneğin:

./configure --prefix=/usr && make && sudo make install

Temel olarak yapılandırma başarılı olursa, make derleme için çalıştırılır ve başarılı olursa make programı yüklemek için root olarak çalıştırılır. Bunu çoğunlukla işlerin işe yarayacağından emin olduğumda kullanıyorum ve ilerlemeyi 'izlemek' değil yığın akışına bakmak gibi diğer önemli şeyleri yapmama izin veriyor.

Bazen gerçekten taşınıyorum ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Bunu, örneğin sıfırlama kutusundan bir linux yaparken yaparım.


2
REPL'de iyi, ama senaryolar set -o errexitiçin Bash'i tercih ederim .
Franklin Yu

19

&&birlikte komut dizeleri. Ardışık komutlar yalnızca öncekiler başarılı olursa çalışır.

Benzer şekilde, ||önceki başarısız olursa ardışık komutun yürütülmesine izin verir.

Bkz. Bash Shell Programming .


8

Örneğe bakın:

mkdir test && echo "Something" > test/file

Shell dizin oluşturmaya çalışacak testve daha sonra yalnızca başarılıysa içinde dosya oluşturmayı deneyecektir.

Dolayısıyla, bunlardan biri başarısız olursa bir dizi adımı kesebilirsiniz.


8

İlk ifade başarılı bir şekilde sona ererse ikinci bir cümle çalıştırmaktır. Bir if ifadesi gibi:

 if (1 == 1 && 2 == 2)
  echo "test;"

İlk denemesi 1 == 1 ise, bu doğruysa 2 == 2 olup olmadığını kontrol eder


1
Birisi bu sorunun neden tökezleyen kullanıcılar için neden indirildiğini açıklayabilir mi?
user3243242

1
@ user3243242 yanlış değil, sadece &&
dan

ifTestlerin bash'da nasıl çalıştığı hakkında harika bir fikir . Hiç bir zaman karşılaştırma komutları zinciri gibi düşünmedim, bunlardan herhangi biri başarısız olduğunda kırıldı. Yani benim oyumu aldın :)
PiRK

1
Sonuç olarak, ||komutlardan birini başarılı olana kadar zincirlemek için zıt davranışı elde edebilirsiniz : eei || leu || uie || echo prout3 || echo "never executed"
PiRK

7

command_1 && command_2: command_2 komutunu yalnızca command_1 başarıyla yürütüldüğünde yürüt.

command_1 || command_2: komut_2'yi yalnızca komut_1 başarılı bir şekilde yürütülmediğinde çalıştır.

İçinde, 'if' koşulu gibi bir ana programlama dilinde yürütülür nasıl benzer duygular if (condition_1 && condition_2){...}condition_2 condition_1 varsa ihmal edilecek falseve if (condition_1 || condition_2){...}condition_1 varsa ihmal edilecek condition_2 true. Kodlama için kullandığınız aynı hile :)


'Tam tersi' ile ne demek istediğini bilmiyorum, ama $ echo '1' || echo '2' yalnızca '1' yazdırır. ve $ wrong_command || echo '2' bir hata mesajı ve sonraki satıra '2' yazdırır. Bunun neyin yanlış olduğunu düşündüğünüzü biraz daha açıklayabilir misiniz?
Xiaonin Li

Ho ahbap, dün kesinlikle çok yorgundum. bunun için üzgünüm, sadece ben oldu: / Ben yukarı oy istiyorum istiyorsanız cevap bir şey düzenlemek gerekir (cevabınızı 0 yapmak için, şu anda stackoverflow düzenleme için isteyin böylece yapamam)
7

@Yakın, sorun değil. Bu yüzden sadece bir düzenleme gönderdim. Peki aşağı oyu kaldırabiliyor musunuz?
Xiaonin Li

Evet, tekrar, üzgünüm, gerçekten
Arount

0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Program komutu kontrol edip etmediğini kontrol ettiğinde, program çıkış kodu adı verilen bir sayı oluşturur, her iki koşul da doğruysa çıkış kodu sıfırdır (0), aksi takdirde çıkış kodu pozitif sayıdır. Yalnızca çıkış kodu sıfır (0) üretilirse Eşit görüntülenirken, her iki koşulun da doğru olduğu anlamına gelir.


Stackoverflow'a hoş geldiniz. Lütfen buraya göndermeden önce kod snippet'inizin çalıştığından emin olun. Bunu düzeltmelisinizif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu
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.