Bagaimana saya bisa menjalankan banyak perintah yang memiliki & dalam satu baris perintah?

12

Saya mengalami masalah sakit kepala.

Saya ingin menjalankan perintah mulitple di latar belakang, jadi saya ingin memulainya dalam bash satu per satu. Sangat mudah untuk memulai satu perintah di shell linux di latar belakang, seperti ini:

myCommand &

Memulai beberapa perintah juga mudah, seperti ini:

myCommand1 && myCommand2

atau

myCommand1 ; myCommand2

Tetapi jika saya ingin menjalankan beberapa perintah di latar belakang, saya mencoba format perintah berikut, tetapi gagal:

myCommand1 & && myCommand2 &

atau

myCommand1 & ; myCommand2 &

Kedua format gagal. Bagaimana saya bisa menjalankan banyak perintah yang ada &dalam satu baris perintah?

Jam ZHONG
sumber
2
Tempatkan mereka di sebuah skrip dan jalankan skrip di latar belakang
Panther
Panther, sepertinya menggunakan () dapat membantu memperbaiki masalah ini lebih mudah daripada menggunakan skrip. Mari kita coba memanfaatkan fitur-fitur yang disediakan oleh shell itu sendiri terlebih dahulu, alih-alih menyusun apa yang kita inginkan sendiri. Tapi tentu saja, menggunakan skrip juga bisa memperbaiki masalah ini. Bagaimanapun, terima kasih.
Jam ZHONG
Bagaimana jika saya ingin menjalankan 'tail -F <file1>> <file2>' diikuti oleh 'jobs -l', yang lagi-lagi diikuti oleh 'disown -h% 1'
akskap

Jawaban:

24

Gunakan ().

Jika Anda ingin menjalankannya secara berurutan:

(myCommand1; myCommand2) &

atau

(myCommand1 &) && (myCommand2 &)

Jika Anda ingin mereka menjalankan paralel:

myCommand1 & myCommand2 &

Dalam bash, Anda juga dapat menggunakan ini (spasi di belakang {dan; wajib):

{ myCommand1 && myCommand2; } &
Rinzwind
sumber
3
(myCommand1 &) && (myCommand2 &)akan berjalan myCommand2meskipun myCommand1gagal.
terdon
() dapat membantu bash untuk membedakan tanda & & &&. Jadi gunakan saja () untuk memisahkan unit eksekusi ketika kita ingin menggunakan tombol & dan &&.
Jam ZHONG
16

Saya kira Anda menginginkan ini:

myCommand1 & myCommand2 &

Ini mulai myCommand1dan mengirimkannya ke latar belakang karena diikuti oleh ampersand, lalu segera memulai myCommand2dan mengirimkan juga ini ke latar belakang, karena itu melepaskan shell lagi.

Daftar

Untuk pemahaman yang lebih baik, Anda dapat mengganti pipa dengan perintah di sini.

Daftar adalah urutan satu atau lebih jaringan pipa yang dipisahkan oleh salah satu operator ; , & , && , atau || , dan secara opsional dihentikan oleh salah satu dari ; , & , atau .

Jika perintah diakhiri oleh operator kontrol & , shell mengeksekusi perintah di latar belakang dalam sebuah subkulit. Shell tidak menunggu perintah selesai, dan status kembali adalah 0. Perintah dipisahkan oleh a ; dieksekusi secara berurutan; shell menunggu setiap perintah berakhir pada gilirannya. Status kembali adalah status keluar dari perintah terakhir yang dijalankan.

Daftar AND dan OR adalah urutan dari satu atau beberapa saluran pipa yang dipisahkan oleh && dan || masing-masing mengendalikan operator.
Sumber:man bash

Mari kita bagi menjadi contoh. Anda dapat membuat daftar dengan menggabungkan perintah dan memisahkannya dengan salah satu dari ini ; & && ||::

command1 ; command2  # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2  # runs simultaneously

Anda dapat mengakhiri daftar dengan salah satu dari ini: ; & <newline>.
Biasanya Anda menjalankan perintah atau daftar dengan menekan Enter, itu sama dengan <newline>. Titik koma ;memiliki tujuan yang sama terutama dalam skrip. &Namun Ampersand memulai perintah dalam subkulit di latar belakang, segera melepaskan shell.

Anda dapat menggunakan ()kurung bundar atau keriting {}untuk daftar grup lebih lanjut, perbedaannya adalah bahwa kurung bundar menelurkan subkulit dan yang keriting tidak. Kurung keriting membutuhkan spasi setelah yang pertama dan titik koma atau baris baru sebelum braket penutup. Sebagai contoh:

# if c1 succeeds start a shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) & 
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &

Ini bisa menjadi sangat rumit, jika Anda tidak yakin menggunakan truedan falseuntuk menguji apakah konstruksi berfungsi seperti yang diharapkan:

$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2

Kontrol Pekerjaan

The jobsperintah menampilkan daftar pekerjaan latar belakang yang berjalan atau baru saja selesai di shell saat ini. Ada sejumlah pintasan keyboard dan perintah untuk kontrol pekerjaan:

  • Ctrl+ Zmengetik karakter yang ditangguhkan yang menyebabkan proses yang sedang berjalan di latar depan dihentikan, tidak dihentikan, tetapi tetap ada dalam jobsdaftar
  • Ctrl+ Ymengetik karakter penundaan tertunda yang menyebabkan proses yang sedang berjalan di latar depan dihentikan ketika mencoba membaca input dari terminal
  • fg= %membawa proses ke latar depan memulainya jika perlu, Anda dapat menentukan proses sebagai berikut:

     %       # last process in the jobs list
     %1      # 1st process in the jobs list
     %abc    # process beginning with the string “abc”
     %?abc   # process containing the string “abc” anywhere
    
  • bg= %&membawa proses ke latar belakang memulainya jika perlu:

     %&      # last process in the jobs list
     %1&     # 1st process in the jobs list
     %abc&   # process beginning with the string “abc”
     %?abc&  # process containing the string “abc” anywhere
    
  • wait menunggu proses latar belakang selesai dan mengembalikan status terminasi:

     wait %1 # 1st process in the jobs list

    Bayangkan Anda memulai proses yang panjang ( jobstunjukkan nomor 3) dan kemudian sadari bahwa Anda ingin komputer ditangguhkan saat selesai, ditambah echopesan jika prosesnya tidak berhasil:

     wait %3 || echo failed ; systemctl suspend
pencuci mulut
sumber
Tetapi penting untuk berhati-hati dengan && itu tergantung pada apa yang dikembalikan oleh perintah , jadi kita perlu memastikan bahwa apa pun yang kita panggil sebenarnya mengembalikan sesuatu yang bash anggap sebagai nilai yang sebenarnya ..?
mathreadler
@ mathreadler Kecuali jika Anda berbicara tentang beberapa skrip pengguna yang dibuat dengan buruk, nilai keluar didefinisikan dengan sangat baik (lihat man bash) dan digunakan secara luas persis seperti yang dimaksudkan AFAIK - Saya tidak pernah mengalami sesuatu yang aneh.
hidangan penutup
tepatnya, orang harus berhati-hati tentang skrip pengguna yang dibuat dengan buruk. Mereka memang ada dan bisa menyusahkan untuk menemukan bug seperti itu. Askubuntu tidak mengizinkan saya untuk "@ hidangan penutup" Anda.
mathreadler
Ah oke, itu masuk akal sekarang karena Anda menyebutkannya.
mathreadler