Mana yang lebih baik: menggunakan; atau && untuk menjalankan beberapa perintah dalam satu baris?

428

Dalam tutorial dan caranya, saya sering melihat perintah digabungkan. Misalnya,

sudo apt-get update && sudo apt-get install pyrenamer

Tampaknya ada empat konektor mungkin: &, &&, ||dan ;. Meskipun & konektornya jelas bagi saya (mengirimkan proses ke latar belakang dan membiarkan terminal tersedia), tidak jelas apa perbedaan antara &&dan ;. Dan saya tidak tahu ||sampai komentar Kaya.

Pertanyaan-pertanyaan berikut berhubungan dengan perbedaan antara kedua konektor, tetapi sebagian besar melakukannya di komentar:

Jadi, inilah sejumlah pertanyaan terkait:

  1. Apa perbedaan antara ;dan &&?
  2. Kapan Anda harus menggunakannya masing - masing? Akan menyenangkan untuk melihat beberapa use case: jika saya ingin menjalankan perintah dan kemudian setelah itu mematikan komputer saya, konektor mana yang harus saya pilih?
  3. Apa keuntungan dan bahayanya ? Robie Basak menyebutkan dalam komentar untuk jawaban ini bahwa perintah seperti cd /somewhere_else; rm -Rf *dapat memiliki konsekuensi yang merusak jika elemen pertama dalam rantai perintah gagal, misalnya.
  4. Jika relevan, dari mana asalnya?
jangan
sumber
7
Ada konektor lain yang mungkin belum Anda temui: ||sama dengan &&kecuali bahwa ia hanya menjalankan perintah kedua jika yang pertama keluar dengan status bukan-nol (tidak berhasil).
Kaya
4
Juga perhatikan bahwa menjalankan skrip Anda dengan set -eakan menghentikan skrip pada kegagalan seolah-olah semua perintah terhubung dengan &&.
choroba
stackoverflow.com/questions/3573742/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
3
Tidak ada yang menjawab Qn 4 ... Saya mencurigai perilaku && dan || terinspirasi oleh bahasa pemrograman C. Dalam kasus (x && y), jika x mengevaluasi ke false, seluruh ekspresi harus salah sehingga kompiler dapat mengoptimalkan evaluasi y, jika itu mahal. Standar C dan C ++ modern sebenarnya membutuhkan optimasi ini, sehingga program dapat dengan aman menganggap bahwa y tidak akan dievaluasi jika x salah. Misalnya, (ptr && ptr-> hari> 31) tidak akan mogok meskipun ptr adalah nol. Juga dalam C, pernyataan diakhiri dengan; terlepas dari apakah ada pernyataan lain pada baris yang sama atau tidak.
Kevin

Jawaban:

772

Contekan:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.
Mendongkrak
sumber
19
Dan tentu saja A & B &,: Jalankan A di latar belakang, kemudian jalankan B di latar belakang (terlepas dari keberhasilan) dan kembalikan kontrol ke shell. Ini sering bekerja hampir sama dengan menjalankan kedua proses pada saat yang sama.
Penebusan Terbatas
4
apakah mungkin untuk mengatakan: jalankan di latar belakang, diikuti oleh b di latar belakang hanya jika berhasil? (Saya kira &&&?)
user230910
15
@ user230910: itu akan menjadi (A && B) &.
leftaroundabout
5
Bisakah Anda merujuk dokumen otoritatif untuk ini?
Jaime Hablutzel
@ Jack Ketika dieksekusi dari Cronjob, itu tidak cukup mengikuti aturan ini, tahu mengapa? Untuk file python
CodeGuru
77

&&hanya menjalankan perintah kedua jika yang pertama keluar dengan status 0 (berhasil). ;menjalankan kedua perintah, bahkan jika yang pertama keluar dengan status bukan nol.

Contoh Anda dengan &&dapat diparafrasekan sebagai

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi
choroba
sumber
Terima kasih. Saya telah memperbarui pertanyaan untuk memastikan berbagai subquestions mudah dibedakan.
don.joey
5
@Private: Anda harus menggunakan ;jika perintah kedua tidak membutuhkan yang sebelumnya untuk berhasil.
choroba
31

Menggunakan ;akan mengeksekusi perintah terlepas dari apakah perintah pertama berhasil atau tidak.

menggunakan &&jalankan perintah ke-2 hanya ketika perintah pertama berhasil dijalankan (status 0).

Keduanya digunakan pada perspektif yang berbeda. Seperti untuk proses yang lebih lama, katakanlah untuk instalasi Anda perlu mengkompilasi dan menginstalnya. kamu harus make && make install. Jadi instal hanya akan berjalan jika makeberhasil.

Jadi untuk perintah dependen yang harus Anda gunakan &&

Peras bash, atau perintah dengan perintah independen digunakan ;

Jadi, jika Anda ingin mematikan komputer meskipun pekerjaan pertama gagal digunakan ;, tetapi jika ingin berhasil sepenuhnya pekerjaan pertama memulai penggunaan shutdown&&

Web-E
sumber
14

a ; bakan berjalan b terlepas dari status keluar dari a. a && bakan berjalan b hanya jika berhasil.

Ini perlu dan cukup untuk menjawab 3 pertanyaan pertama. Secara khusus, 2 terlalu luas, dan tidak dapat diberikan "satu" jawaban definitif - taruhan terbaik Anda adalah memutuskan berdasarkan kasus per kasus.

Adapun pertanyaan ke-4: Mereka sintaks Bash .

Tidak ada bahaya intrinsik dalam menggunakan keduanya. Sekali lagi, definisi di atas sudah cukup. Ini menyiratkan bahwa Anda akan menulis &&kapan bmemiliki efek yang tidak diinginkan jika atidak berhasil. Tidak perlu aturan atau penjelasan lebih lanjut, IMHO.

ignis
sumber
1

SEBUAH; B # Jalankan A dan kemudian B, terlepas dari keberhasilan A

A && B # Jalankan B jika dan hanya jika A berhasil

A || B # Jalankan B jika dan hanya jika A gagal

A & # Jalankan A di latar belakang.

Aturan praktis yang sangat bagus. Saya akan menambahkan bahwa dalam beberapa kasus, menggunakan perintah ini dalam subkulit masuk akal ketika kita ingin menganggapnya sebagai satu unit atau kita tidak ingin memasangkan beberapa hasil operasi dengan shell saat ini.

Contoh:

-menghasil output dari dua perintah:

(ls foo; ls bar) > single-result.txt

-masuk ke direktori dan melakukan perintah dari sana sementara tidak mengubah direktori shell saat ini:

(cd target-directory && jar -xf ../my-jar)
davidxxx
sumber