Pertanyaan Apakah ada perbedaan antara '&&' dan ';' simbol dalam terminal BASH standar?


Mereka tampaknya memberi sinyal BASH untuk memulai dengan perintah lain mengikuti simbol-simbol tetapi apakah ada perbedaan yang jelas?


51
2018-01-27 17:01


asal




Jawaban:


Dengan baris ini:

command1 && command2

command2 akan dieksekusi jika (dan hanya jika) command1 mengembalikan status exit nol, sedangkan pada baris ini:

command1 ; command2

baik command1 dan command2 akan dieksekusi. Titik koma memungkinkan Anda mengetik banyak perintah pada satu baris.


65
2018-01-27 17:12



Menarik! Saya pikir itu mungkin hanya menjadi cara yang lebih nyaman. Terima kasih!


Anda dapat mencoba perbedaan untuk diri sendiri:

  1. ls /invalid/path && echo "hello!"
    karena / invalid / path tidak ada, ls tidak bisa menunjukkan daftar direktori. Ini akan gagal dengan pesan kesalahan: "ls: / invalid / path: Tidak ada file atau direktori semacam itu".
    Itu babak kedua dari perintah (echo "hello!") adalah bahkan tidak pernah dieksekusi karena babak pertama gagal.

  2. ls /invalid/path ; echo "hello!"
    Pesan kesalahan yang sama muncul seperti sebelumnya, tetapi kali ini, bagian kedua dijalankan!
    ls: / invalid / path: Tidak ada file atau direktori semacam itu
    Halo!

Mengapa ini berguna?
Misalkan Anda ingin mengekstrak file bernama archive.tar.gz
Anda bisa menggunakan perintah tar zxvf archive.tar.gz && rm archive.tar.gz.
Jika karena alasan apa pun ekstraksi arsip gagal, bagian kedua tidak dieksekusi! Anda dapat mencoba lagi.

Jika Anda menggunakan; dalam situasi yang sama, arsip dihapus dan Anda tidak dapat mencoba lagi.


40
2018-01-27 17:37



Contoh yang fantastis. Terima kasih banyak.


&& aku s AND, artinya perintah kedua hanya akan dijalankan jika yang pertama mengembalikan true (tidak ada kesalahan).


8
2018-01-27 17:11



&& adalah "kemudian" (bukan "dan") ... lihat jawaban saya - Peter.O
@ aku akan mengatakan itu sebuah "dan" dengan evaluasi sirkuit pendek - jika bagian pertama tidak benar, ia tahu bahwa hasil total harus salah, sehingga melewatkan bagian kedua. Tetapi setuju bahwa menganggapnya sebagai "lalu" jarang membuat banyak perbedaan dalam konteks ini. - j-g-faustus
@fred Meskipun secara konseptual mungkin lebih mudah untuk memahaminya seperti itu, saya tidak setuju dengan pernyataan Anda. Idenya hanya dengan apa saja  AND eksekusi parameter ke-2 menjadi tidak relevan jika yang pertama sama false sehingga kode yang mendasari dioptimalkan untuk menunda evaluasi parameter ke-2 sampai ia tahu apa yang pertama. - Ward Muylaert
@fred Saya tidak yakin poin apa yang sedang dicoba. && hanya operator biner, fungsi. Satu-satunya hal "khusus" adalah notasi infiks (yang merupakan standar untuk sebagian besar operator semacam ini) dan penundaan eksekusi operan kedua. Eksekusi yang tertunda itu memang memberinya kemampuan untuk digunakan sebagai sesuatu yang dapat dilihat secara konseptual sebagai if pernyataan dalam hal ini, tetapi itu tidak mengambil dari fakta bahwa penggunaan yang awalnya dimaksudkan adalah dalam bersyarat dari yang sebenarnya if pernyataan. Penggunaan di sini benar-benar lebih dari "hack". - Ward Muylaert
@fred Tentu saja itu bukan operator terner, itu hanya merupakan suksesi dua operasi a && b || c = (a && b) || c. Urutan evaluasi sederhana. Benar-benar tidak ada misteri di sana. Jika Anda akan menulisnya seperti fungsi-fungsi khas Anda, itu hanya akan terlihat seperti or(and(a, b), c). Logika ini sama dalam sebuah if bersyarat seperti halnya ketika memasukkannya langsung ke baris perintah karena && dan || adalah operator, mereka mengambil dua operan dan mereka kembali lagi. - Ward Muylaert


Memperbarui: Saya telah menambahkan sebagai skrip untuk menyoroti beberapa kemungkinan perangkap:

Karena tidak ada orang lain yang menyebut "| |", aku akan

Perbarui2: beberapa kata-ulang penting di sini
&& seperti "kemudian" dari pernyataan "jika" yang merespons "benar"

|| aku s TIDAK seperti "lain" dari pernyataan "jika" ..
|| seperti "lalu" dari pernyataan "jika" yang merespons "salah"

Lebih spesifik, & & menguji $? mengembalikan nilai dari sebelumnya  paling baru dieksekusi pernyataan dan melewati kontrol ke pernyataan atau sub-shell segera mengikuti && ... hanya melewati kontrol jika $? adalah benar.

|| mirip, dan sering terlihat mengikuti & & pernyataan, tetapi tes untuk a Salah mengembalikan nilai ($?) dari sebelumnya  paling baru dieksekusi pernyataan... NB!, Nota Bene! Perhatikan dengan baik! .... jika pernyataan predecing adalah & & pernyataan yang membuat kesalahan kembali ketika Anda mengharapkannya benar, lalu || akan menanggapi false, jadi mencampur keduanya pada baris yang sama mungkin berisiko

Poin utama yang saya coba buat adalah sehubungan dengan kesalahan yang saya buat. yaitu:
 ## [[kondisi]] ​​&& A || B
aku s tidak tidak berperilaku seperti terner C / C ++ style. yaitu:
// (kondisi)? A: B
Lihat skrip di bawah ini untuk contoh hasil "tak terduga" dari "A"

Tes dasar dan && dan || pernyataan semuanya harus pada baris yang sama ...


Jalankan skrip ini untuk melihat di mana hal-hal yang salah ketika menggunakan && dan ||
Itu paling baru dieksekusipernyataan mungkin bukan yang Anda harapkan ..

[[kondisi]] ​​&& echo Halo || echo Selamat tinggal .... biasanya aman,
Karena gema yang terbentuk dengan baik akan kembali benar.
tapi bagaimana dengan mengakses file yang tidak keluar?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \$0  0   rc=$? ..&&.. condition is true" || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && echo  " ((1!=1)) rc=$? ..&&.. condition is true" || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && echo "  \$0  1   rc=$? ..&&.. condition is true" || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo  ======
 ((1==1)) || echo  " ((1==1)) rc=$? ..||.. condition is true" && echo  " ((1==1)) rc=$? ..&&.. condition is false"
  $0  0   || echo "  \$0  0   rc=$? ..||.. condition is true" && echo "  \$0  0   rc=$? ..&&.. condition is false"
 ((1!=1)) || echo  " ((1!=1)) rc=$? ..||.. condition is true" && echo  " ((1!=1)) rc=$? ..&&.. condition is false"
  $0  1   || echo "  \$0  1   rc=$? ..||.. condition is true" && echo "  \$0  1   rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"

exit 


6
2018-02-09 06:42



Itu sangat menarik. Terima kasih!


mencoba

false && echo "hello"

dan

Salah ; echo "hello"

Lihat perbedaannya


1
2018-02-09 06:19





Perintah (fungsi, dalam kasus skrip) setelah && dijalankan tergantung pada RETVAL dari perintah pertama (fungsi, dalam kasus skrip). Ini memaksa perintah pertama untuk mengembalikan nilai 0, jika berhasil. Kami dapat memeriksa nilai kembali untuk mengeksekusi perintah lebih lanjut.


0
2018-02-09 08:07