Apa yang dimaksud dengan operator kontrol dan pengalihan shell?

246

Saya sering melihat tutorial online yang menghubungkan berbagai perintah dengan simbol yang berbeda. Sebagai contoh:

command1 |  command2
command1 &  command2
command1 || command2    
command1 && command2

Orang lain tampaknya menghubungkan perintah ke file:

command1  > file1
command1  >> file1

Benda apa ini? Mereka dipanggil apa? Apa yang mereka lakukan? Apakah ada lebih banyak dari mereka?


Meta utas tentang pertanyaan ini. .

terdon
sumber

Jawaban:

340

Ini disebut operator shell dan ya, ada lebih banyak dari mereka. Saya akan memberikan gambaran singkat tentang yang paling umum di antara dua kelas utama, operator kontrol dan operator pengalihan , dan bagaimana mereka bekerja sehubungan dengan bash shell.

A. Kontrol operator

Dalam bahasa perintah shell, token yang melakukan fungsi kontrol.
Ini adalah salah satu dari simbol berikut:

&   &&   (   )   ;   ;;   <newline>   |   ||

Dan |&dalam bash.

Sebuah !adalah tidak operator control tapi Reserved Firman . Ini menjadi BUKAN [operator negasi] logis di dalam Ekspresi Aritmatika dan konstruksi uji dalam (sementara masih membutuhkan pembatas ruang).

A.1 Daftar terminator

  • ; : Akan menjalankan satu perintah setelah yang lain selesai, terlepas dari hasil yang pertama.

    command1 ; command2

    Pertama command1dijalankan, di latar depan, dan setelah selesai, command2akan dijalankan.

    Baris baru yang tidak dalam string literal atau setelah kata kunci tertentu tidak setara dengan operator titik koma. Daftar ;perintah sederhana terbatas masih merupakan daftar - karena dalam parser shell masih harus terus membaca dalam perintah sederhana yang mengikuti ;perintah sederhana terbatas sebelum dieksekusi, sedangkan baris baru dapat membatasi seluruh daftar perintah - atau daftar daftar. Perbedaannya halus, tetapi rumit: mengingat shell tidak memiliki keharusan sebelumnya untuk membaca data mengikuti baris baru, baris baru menandai titik di mana shell dapat mulai mengevaluasi perintah-perintah sederhana yang sudah dibaca, sedangkan ;semi-colon tidak tidak.

  • & : Ini akan menjalankan perintah di latar belakang, memungkinkan Anda untuk terus bekerja di shell yang sama.

     command1 & command2

    Di sini, command1diluncurkan di latar belakang dan command2mulai berjalan di latar depan segera, tanpa menunggu untuk command1keluar.

    Baris baru setelahnya command1adalah opsional.

A.2 Operator logis

  • && : Digunakan untuk membangun DAN daftar, ini memungkinkan Anda untuk menjalankan satu perintah hanya jika yang lain berhasil keluar.

     command1 && command2

    Di sini, command2akan dijalankan setelah command1selesai dan hanya jika command1berhasil (jika kode keluarnya adalah 0). Kedua perintah dijalankan di latar depan.

    Perintah ini juga bisa ditulis

    if command1
    then command2
    else false
    fi
    

    atau hanya if command1; then command2; fijika status pengembalian diabaikan.

  • || : Digunakan untuk membuat daftar ATAU, ini memungkinkan Anda untuk menjalankan satu perintah hanya jika yang lain tidak berhasil.

     command1 || command2

    Di sini, command2hanya akan berjalan jika command1gagal (jika mengembalikan status keluar selain 0). Kedua perintah dijalankan di latar depan.

    Perintah ini juga bisa ditulis

    if command1
    then true
    else command2
    fi
    

    atau dengan cara yang lebih pendek if ! command1; then command2; fi.

    Perhatikan itu &&dan ||asosiatif kiri; lihat diutamakan operator logika shell &&, || untuk informasi lebih lanjut.

  • !: Ini adalah kata yang dilindungi undang-undang yang bertindak sebagai operator "bukan" (tetapi harus memiliki pembatas), digunakan untuk meniadakan status pengembalian suatu perintah - mengembalikan 0 jika perintah mengembalikan status bukan nol, mengembalikan 1 jika mengembalikan status 0 Juga TIDAK logis untuk testutilitas.

    ! command1
    
    [ ! a = a ]
    

    Dan operator BUKAN yang sebenarnya dalam Ekspresi Aritmatika:

    $ echo $((!0)) $((!23))
    1 0
    

A.3 Operator pipa

  • |: Operator pipa, meneruskan output dari satu perintah sebagai input ke yang lain. Perintah yang dibangun dari operator pipa disebut pipeline .

     command1 | command2

    Output apa pun yang dicetak oleh command1diteruskan sebagai input command2.

  • |&: Ini adalah singkatan untuk 2>&1 |dalam bash dan zsh. Ini melewati standar output dan standard error dari satu perintah sebagai input ke perintah lainnya.

    command1 |& command2

A.4 Tanda baca daftar lainnya

;;digunakan hanya untuk menandai akhir dari pernyataan kasus . Ksh, bash dan zsh juga mendukung ;&untuk masuk ke kasus berikutnya dan ;;&(tidak di ATT ksh) untuk melanjutkan dan menguji kasus-kasus berikutnya.

(dan )digunakan untuk mengelompokkan perintah dan meluncurkannya dalam subkulit. {dan }juga perintah grup, tetapi jangan meluncurkannya dalam subkulit. Lihat jawaban ini untuk diskusi tentang berbagai jenis kurung, kurung dan kurung kurawal dalam sintaksis shell.

B. Operator Pengalihan

Operator Pengalihan

Dalam bahasa perintah shell, token yang melakukan fungsi pengalihan. Ini adalah salah satu dari simbol berikut:

<     >     >|     <<     >>     <&     >&     <<-     <>

Ini memungkinkan Anda untuk mengontrol input dan output dari perintah Anda. Mereka dapat muncul di mana saja dalam perintah sederhana atau dapat mengikuti perintah. Pengalihan diproses sesuai urutan kemunculannya, dari kiri ke kanan.

  • < : Memberikan input ke perintah.

    command < file.txt

    Di atas akan mengeksekusi commandpada isi file.txt.

  • <>: sama seperti di atas, tetapi file terbuka dalam mode baca + tulis alih-alih hanya baca :

    command <> file.txt

    Jika file tidak ada, itu akan dibuat.

    Operator itu jarang digunakan karena perintah umumnya hanya membaca dari stdin mereka, meskipun itu bisa berguna dalam sejumlah situasi tertentu .

  • > : Mengarahkan output perintah ke file.

    command > out.txt

    Di atas akan menyimpan output commandsebagai out.txt. Jika file ada, isinya akan ditimpa dan jika tidak ada maka akan dibuat.

    Operator ini juga sering digunakan untuk memilih apakah sesuatu harus dicetak ke kesalahan standar atau output standar :

    command >out.txt 2>error.txt

    Pada contoh di atas, >akan mengarahkan output standar dan 2>mengarahkan ulang kesalahan standar. Output juga dapat diarahkan menggunakan 1>tetapi, karena ini adalah default, 1biasanya dihilangkan dan ditulis hanya sebagai >.

    Jadi, untuk menjalankan commandpada file.txtdan menyimpan output dalam out.txtdan pesan kesalahan di error.txtAnda akan menjalankan:

    command < file.txt > out.txt 2> error.txt
  • >|: Apakah sama dengan >, tetapi akan menimpa target, bahkan jika shell telah dikonfigurasi untuk menolak menimpa (dengan set -Catau set -o noclobber).

    command >| out.txt

    Jika out.txtada, output dari commandakan mengganti kontennya. Jika tidak ada maka akan dibuat.

  • >>: Apakah sama dengan >, kecuali bahwa jika file target ada, data baru ditambahkan.

    command >> out.txt

    Jika out.txtada, output dari commandakan ditambahkan padanya, setelah apa pun yang sudah ada di dalamnya. Jika tidak ada maka akan dibuat.

  • &>, >&, >>&Dan &>>: (non-standar). Arahkan masing-masing kesalahan standar dan output standar, menggantikan atau menambahkan.

    command &> out.txt

    Baik standard error dan output standar commandakan disimpan out.txt, menimpa isinya atau membuatnya jika tidak ada.

    command &>> out.txt

    Seperti di atas, kecuali jika out.txtada, output dan kesalahan commandakan ditambahkan padanya.

    The &>varian berasal bash, sedangkan >&varian berasal dari csh (dekade sebelumnya). Keduanya bertentangan dengan operator shell POSIX lain dan tidak boleh digunakan dalam shskrip portabel .

  • <<: Dokumen di sini. Ini sering digunakan untuk mencetak string multi-line.

     command << WORD
         Text
     WORD
    

    Di sini, commandakan mengambil semuanya hingga menemukan kemunculan berikutnya WORD, Textdalam contoh di atas, sebagai input. Meskipun WORDsering EoFatau variasi daripadanya, itu bisa berupa string alfanumerik (dan bukan hanya) yang Anda suka. Ketika WORDdikutip, teks dalam dokumen di sini diperlakukan secara harfiah dan tidak ada ekspansi yang dilakukan (pada variabel misalnya). Jika tidak dikutip, variabel akan diperluas. Untuk detail lebih lanjut, lihat manual bash .

    Jika Anda ingin menyalurkan output command << WORD ... WORDlangsung ke perintah atau perintah lain, Anda harus meletakkan pipa pada baris yang sama dengan << WORD, Anda tidak dapat meletakkannya setelah KATA penghentian atau pada baris berikutnya. Sebagai contoh:

     command << WORD | command2 | command3...
         Text
     WORD
    
  • <<<: Berikut string, mirip dengan dokumen di sini, tetapi dimaksudkan untuk satu baris. Ini hanya ada di port Unix atau rc (dari mana asalnya), zsh, beberapa implementasi ksh, yash dan bash.

    command <<< WORD

    Apa pun yang diberikan saat WORDdiperluas dan nilainya diteruskan sebagai input command. Ini sering digunakan untuk meneruskan konten variabel sebagai input ke perintah. Sebagai contoh:

     $ foo="bar"
     $ sed 's/a/A/' <<< "$foo"
     bAr
     # as a short-cut for the standard:
     $ printf '%s\n' "$foo" | sed 's/a/A/'
     bAr
     # or
     sed 's/a/A/' << EOF
     $foo
     EOF
    

Beberapa operator lain ( >&-, x>&y x<&y) dapat digunakan untuk menutup atau menggandakan deskriptor file. Untuk detailnya, silakan lihat bagian yang relevan dari manual shell Anda (di sini misalnya untuk bash).

Itu hanya mencakup operator paling umum dari kerang mirip Bourne. Beberapa shell memiliki beberapa operator pengalihan tambahan mereka sendiri.

Ksh, bash dan zsh juga memiliki konstruksi <(…), >(…)dan =(…)(yang terakhir zshhanya dalam konstruksi ). Ini bukan pengalihan, tetapi proses substitusi .

terdon
sumber
2
Mungkin akan bermanfaat untuk dicatat bahwa tidak semua shell sama, dan secara khusus menyoroti fitur spesifik bash.
Greg Hewgill
1
@GregHewgill ya, saya keluar dari sana dengan mengatakan bahwa saya sedang mendiskusikan sehubungan dengan bash. Ini dipersiapkan sebagai tanya jawab kanonik untuk menutup berbagai pertanyaan "Apa yang dilakukan makhluk aneh ini" dan kebanyakan dari mereka adalah pengguna bash. Saya berharap orang lain akan melempar dan menjawab untuk cangkang non-bash, tetapi menyoroti bash-spesifik tertentu sangat masuk akal. Saya harus memeriksa, saya tidak tahu yang mana yang berada di atas kepala saya.
terdon
&>,, >>>dan <<<semuanya non-posix seperti referensi untuk karakter non-alphanum tidak-saja dalam nama-doc di sini. Jawaban ini juga membahas sangat sedikit tentang bagaimana mereka bekerja - misalnya, hampir lebih buruk daripada tidak berguna untuk berbicara tentang perintah sederhana dan perintah tanpa menjelaskan apa ini dan bagaimana shell memutuskan.
mikeserv
@ mikeserv terima kasih. Mereka bekerja pada bash dan zsh. Saya tidak tahu apa, jika ada, yang benar-benar spesifik untuk bash dalam daftar itu. Saya harus membaca ini dan menambahkan cangkang masing-masing karya tetapi itu akan melibatkan mencari tahu dulu.
terdon
1
@ Arc676 Tidak, mereka tidak mengevaluasi benar atau salah, itu konteks yang sama sekali berbeda. Ini hanya berarti bahwa nilai keluar non-0 menunjukkan masalah (tidak false) dan kode keluar 0 menunjukkan keberhasilan (tidak true). Itu selalu menjadi jalan dan cukup standar. Kode keluar non-0 menunjukkan kesalahan di setiap lingkungan yang saya tahu.
terdon
61

Peringatan tentang '>'

Pemula Unix yang baru belajar tentang pengalihan I / O ( <dan >) sering mencoba hal-hal seperti

commandinput_file > the_same_file

atau

command ... < file      > the_same_file

atau, hampir setara,

file kucing | command …> the_same_file

( grep, sed, cut, sort, Dan spelladalah contoh perintah yang orang tergoda untuk digunakan dalam konstruksi seperti ini.) Pengguna terkejut menemukan bahwa skenario ini menghasilkan file menjadi kosong.

Sebuah nuansa yang tampaknya tidak disebutkan dalam jawaban lainnya dapat ditemukan bersembunyi dalam kalimat pertama dari Pengalihan bagian dari bash (1) :

Sebelum perintah dieksekusi, input dan outputnya dapat dialihkan menggunakan notasi khusus yang ditafsirkan oleh shell.

Lima kata pertama harus tebal, miring, bergaris bawah, diperbesar, berkedip, berwarna merah, dan ditandai dengan tanda seru dalam segitiga merahikon, untuk menekankan fakta bahwa shell melakukan pengalihan yang diminta sebelum perintah dijalankan . Dan ingat juga

Pengalihan output menyebabkan file ... dibuka untuk ditulis .... Jika file tidak ada itu dibuat; jika memang ada itu dipotong ke ukuran nol.

  1. Jadi, dalam contoh ini:

    sort roster > roster

    shell membuka rosterfile untuk ditulis, memotongnya (yaitu, membuang semua isinya), sebelum sortprogram mulai berjalan. Secara alami, tidak ada yang bisa dilakukan untuk memulihkan data.

  2. Orang mungkin naif mengharapkan itu

    tr "[:upper:]" "[:lower:]" < poem > poem

    mungkin lebih baik. Karena shell menangani pengalihan dari kiri ke kanan, shell terbuka poemuntuk membaca (untuk trinput standar) sebelum membukanya untuk menulis (untuk output standar). Tapi itu tidak membantu. Meskipun urutan operasi ini menghasilkan dua pegangan file, mereka berdua menunjuk ke file yang sama. Ketika shell membuka file untuk dibaca, isinya masih ada, tetapi mereka masih musnah sebelum program dieksekusi. 

Jadi, apa yang harus dilakukan?

Solusi meliputi:

  • Periksa apakah program yang Anda jalankan memiliki kapabilitas sendiri, internal, untuk menentukan ke mana output berjalan. Ini sering ditunjukkan dengan token -o(atau --output=). Khususnya,

    sort roster -o roster

    kira-kira setara dengan

    sort roster > roster

    kecuali, dalam kasus pertama, sortprogram membuka file output. Dan cukup pintar untuk tidak membuka file output sampai setelah membaca semua file input.

    Demikian pula, setidaknya beberapa versi sedmemiliki -i(edit i n tempat) pilihan yang dapat digunakan untuk menulis output kembali ke file input (sekali lagi, setelah semua masukan sudah dibaca). Editor seperti ed/ ex, emacs, pico, dan vi/ vim memungkinkan pengguna untuk mengedit file teks dan menyimpan teks diedit di file asli. Perhatikan bahwa ed(setidaknya) dapat digunakan secara non-interaktif.

    • vimemiliki fitur terkait. Jika Anda mengetik , itu akan menulis isi buffer edit , membaca hasilnya, dan memasukkannya ke buffer (mengganti konten asli).:%!commandEntercommand
  • Sederhana tetapi efektif:

    perintah ... input_file > temp_file   && mv temp_file  input_file

    Ini memiliki kelemahan bahwa, jika input_filemerupakan tautan, tautan itu (mungkin) akan digantikan oleh file terpisah. Juga, file baru akan dimiliki oleh Anda, dengan perlindungan default. Secara khusus, ini membawa risiko bahwa file tersebut pada akhirnya akan dapat dibaca dunia, bahkan jika aslinya input_filetidak.

    Variasi:

    • commandinput_file > temp_file && cp temp_file input_file && rm temp_file
      yang masih akan (berpotensi) meninggalkan temp_filedunia terbaca. Bahkan lebih baik:
    • cp input_file temp_file && commandtemp_file > input_file && rm temp_file
      Ini mempertahankan status tautan, pemilik, dan mode (perlindungan) file, berpotensi dengan biaya dua kali lipat I / O. (Anda mungkin perlu menggunakan opsi suka -aatau -paktif cp untuk mengatakannya untuk mempertahankan atribut.)
    • commandinput_file > temp_file &&
      cp --attributes-only --preserve=all input_file temp_file &&
      mv temp_file input_file
      (dipecah menjadi baris terpisah hanya untuk keterbacaan) Ini mempertahankan mode file (dan, jika Anda root, pemilik), tetapi membuatnya dimiliki oleh Anda (jika Anda bukan root), dan menjadikannya baru, file terpisah.
  • Blog ini ("Di-tempat" mengedit file) menyarankan dan menjelaskan

    {rm input_file   &&   command …> input_file ; } < input_file

    Ini mensyaratkan bahwa commandmampu memproses input standar (tetapi hampir semua filter dapat). Blog itu sendiri menyebut ini kludge berisiko dan mencegah penggunaannya. Dan ini juga akan membuat file baru yang terpisah (tidak terkait dengan apa pun), yang dimiliki oleh Anda dan dengan izin default.

  • Paket moreutils memiliki perintah yang disebut sponge:

    perintah ... input_file | spons the_same_file

    Lihat jawaban ini untuk informasi lebih lanjut.

Inilah sesuatu yang mengejutkan saya: sintaksis mengatakan :

[Sebagian besar solusi ini] akan gagal pada sistem file read-only, di mana "read-only" berarti bahwa Anda $HOME akan dapat ditulis, tetapi /tmpakan hanya-baca (secara default). Misalnya, jika Anda memiliki Ubuntu, dan Anda telah mem-boot ke Konsol Pemulihan, biasanya demikian. Juga, operator dokumen di sini <<<tidak akan bekerja di sana, karena /tmpharus dibaca / ditulis karena akan menulis file sementara ke sana juga.
(lih. pertanyaan ini mencakup stracekeluaran d)

Berikut ini mungkin berfungsi dalam kasus itu:

  • Untuk pengguna tingkat lanjut: Jika perintah Anda dijamin untuk menghasilkan jumlah yang sama dari output data karena ada masukan (misalnya, sortatau tr tanpa satu -datau -sopsi), Anda dapat mencoba
    perintah ... input_file | dd = the_same_file conv = notrunc
    Lihat jawaban ini dan jawaban ini untuk informasi lebih lanjut, termasuk penjelasan di atas, dan alternatif yang berfungsi jika perintah Anda dijamin untuk menghasilkan jumlah data output yang sama dengan input atau kurang (misalnya grep,, atau cut). Jawaban-jawaban ini memiliki keuntungan bahwa mereka tidak memerlukan ruang kosong (atau mereka membutuhkan sangat sedikit). Jawaban di atas dari formulir jelas mensyaratkan bahwa ada cukup ruang kosong bagi sistem untuk dapat menyimpan seluruh file input (lama) dan file output (baru) secara bersamaan; ini tidak jelas benar untuk sebagian besar solusi lain (misalnya, dan ) juga. Pengecualian: mungkin akan membutuhkan banyak ruang kosong, karenacommandinput_file > temp_file && …sed -ispongesort … | dd …sort perlu membaca semua inputnya sebelum dapat menulis output apa pun, dan mungkin buffer paling jika tidak semua data dalam file sementara.
  • Hanya untuk pengguna tingkat lanjut:
    commandinput_file 1 <> the_same_file
    mungkin sama dengan ddjawaban di atas. The sintaks membuka file bernama pada file descriptor untuk kedua input dan output , tanpa truncating itu - semacam kombinasi dan . Catatan: Beberapa program (misalnya, dan ) mungkin menolak untuk berjalan dalam skenario ini karena mereka dapat mendeteksi bahwa input dan output adalah file yang sama. Lihat jawaban ini untuk pembahasan di atas, dan skrip yang membuat jawaban ini berfungsi jika perintah Anda dijamin untuk menghasilkan jumlah data output yang sama dengan input atau kurang . Peringatan: Saya belum menguji skrip Peter, jadi saya tidak menjaminnya.n<> filen n<n>catgrep

Jadi, apa pertanyaannya?

Ini telah menjadi topik populer tentang U&L; itu dibahas dalam pertanyaan-pertanyaan berikut:

... dan itu tidak termasuk Super User atau Ask Ubuntu. Saya telah memasukkan banyak informasi dari jawaban atas pertanyaan di atas dalam jawaban ini, tetapi tidak semua. (Yaitu, untuk informasi lebih lanjut, baca pertanyaan-pertanyaan yang tercantum di atas dan jawabannya.)

PS Saya tidak memiliki afiliasi dengan blog yang saya kutip di atas.

Scott
sumber
Karena pertanyaan ini terus muncul, saya pikir saya akan mencoba menulis “jawaban kanonik”. Haruskah saya mempostingnya di sini (dan mungkin menghubungkannya dengan beberapa pertanyaan lain yang lebih banyak diperdagangkan), atau haruskah saya memindahkannya ke salah satu pertanyaan yang benar-benar menimbulkan masalah ini? Juga, apakah ini mungkin situasi di mana pertanyaan harus digabungkan?
Scott
/ tmp Direktori yang disediakan untuk aplikasi yang membutuhkan tempat untuk membuat file sementara. Aplikasi harus diizinkan untuk membuat file dalam direktori ini, tetapi tidak boleh berasumsi bahwa file tersebut disimpan antara doa aplikasi.
mikeserv
@ mikeserv: Ya, (1) Saya mengutip sintaksis, dan (2) saya bilang saya terkejut. Saya pikir, jika sesuatu akan dibaca-tulis, itu akan menjadi /tmp.
Scott
Nah, mengatakan hal @syntaxerror adalah ganda aneh karena, karena saya pikir, dashakan menjadi shell recovery default pada Ubuntu dan tidak hanya tidak mengerti <<<herestring, tetapi juga mendapat pipa anonim untuk <<heredocuments dan tidak main-main dengan ${TMPDIR:-/tmp}untuk itu tujuan sama sekali. Lihat ini atau ini untuk demo tentang penanganan dokumen di sini. Juga mengapa jumlah output yang sama atau kurang peringatan?
mikeserv
@ mikeserv: Ya, dd … conv=notruncdan 1<>jawaban tidak pernah memotong file output, jadi, jika output dari perintah kurang dari input (misalnya, grep), akan ada beberapa byte asli yang tersisa di akhir file. Dan, jika output lebih besar dari input (misalnya, cat -n, nl, atau (berpotensi) grep -n), ada risiko Timpa data lama sebelum Anda membacanya.
Scott
29

Pengamatan lebih pada ;, &, (dan)

  • Perhatikan bahwa beberapa perintah dalam jawaban terdon mungkin nol. Misalnya, bisa dibilang

    command1 ;

    (tanpa command2). Ini setara dengan

    command1

    (Yaitu, itu hanya berjalan command1di latar depan dan menunggu sampai selesai. Sebanding,

    command1 &

    (tanpa command2) akan diluncurkan command1di latar belakang dan kemudian segera mengeluarkan prompt shell lainnya.

  • Sebaliknya, command1 &&, command1 ||, dan command1 |tidak masuk akal. Jika Anda mengetik salah satu dari ini, shell akan (mungkin) mengasumsikan bahwa perintah dilanjutkan ke baris lain. Ini akan menampilkan prompt shell sekunder (lanjutan), yang biasanya diatur ke >, dan terus membaca. Dalam skrip shell, itu hanya akan membaca baris berikutnya dan menambahkannya ke apa yang sudah dibaca. (Hati-hati: ini mungkin bukan yang Anda inginkan terjadi.)

    Catatan: beberapa versi beberapa shell mungkin memperlakukan perintah yang tidak lengkap sebagai kesalahan. Dalam kasus seperti itu (atau, pada kenyataannya, dalam kasus apa pun di mana Anda memiliki perintah yang panjang), Anda dapat meletakkan garis miring terbalik ( \) di akhir baris untuk memberi tahu shell untuk melanjutkan membaca perintah di baris lain:

    command1  &&  \
    command2
    

    atau

    find starting-directory -mindepth 3 -maxdepth 5 -iname "*.some_extension" -type f \
                            -newer some_existing_file -user fred -readable -print
    
  • Seperti kata terdon, (dan )dapat digunakan untuk mengelompokkan perintah. Pernyataan bahwa mereka “tidak benar-benar relevan” dengan diskusi itu masih bisa diperdebatkan. Beberapa perintah dalam jawaban terdon mungkin adalah grup perintah . Sebagai contoh,

    ( command1 ; command2 )  &&  ( command3; command4 )

    Melakukan hal ini:

    • Jalankan command1dan tunggu sampai selesai.
    • Kemudian, terlepas dari hasil menjalankan perintah pertama itu, jalankan command2dan tunggu sampai selesai.
    • Lalu, jika command2berhasil,

      • Jalankan command3dan tunggu sampai selesai.
      • Kemudian, terlepas dari hasil menjalankan perintah itu, jalankan command4dan tunggu sampai selesai.

      Jika command2gagal, hentikan pemrosesan baris perintah.

  • Di luar kurung, |mengikat dengan sangat erat, jadi

    command1 | command2 || command3

    setara dengan

    ( command1 | command2 )  ||  command3

    dan &&dan ||ikat lebih ketat daripada ;, jadi

    command1 && command2 ; command3

    setara dengan

    ( command1 && command2 ) ;  command3

    yaitu, command3akan dieksekusi terlepas dari status keluar dari command1dan / atau command2.

G-Man
sumber
Sempurna, +1! Saya mengatakan mereka tidak relevan karena saya tidak ingin membahas secara mendetail. Saya menginginkan jawaban yang bisa berfungsi sebagai cheatsheet cepat untuk pemula yang bertanya-tanya apa semua coretan aneh di akhir berbagai perintah. Saya tidak bermaksud mengatakan bahwa itu tidak berguna. Terima kasih telah menambahkan semua ini.
terdon
1
Saya prihatin dengan masalah "masa kritis" - jika kita memposting semua yang bisa kita katakan tentang cangkang, kita akan berakhir dengan versi TL; DR kita sendiri dari Bash Reference Manual.
G-Man
Juga layak disebutkan: Tidak seperti dalam bahasa keluarga C, ;dengan sendirinya (atau tanpa perintah sebelumnya) adalah kesalahan sintaks, dan bukan pernyataan kosong. Jadi ; ;ini adalah kesalahan. (Perangkap umum untuk pengguna baru, IMHO). Juga: ;;adalah pembatas khusus, untuk casepernyataan.
muru
1
@uru: Poin bagus, tapi mari kita generalisasikan. Setiap operator control yang dapat muncul antara perintah: ;, &&, ||, &, dan |, kesalahan jika mereka muncul dengan apa-apa sebelumnya mereka. Juga, terdon menjawab ;;(secara singkat) dalam jawabannya.
G-Man
1
@ Kartu Memori: OK, saya melihat dari mana Anda berasal. Kata kuncinya adalah "may"; semua yang saya katakan adalah bahwa saya tidak menjamin bahwa semua shell akan menerima konstruksi seperti itu (yaitu, YMMV). Jelas saya menulis bahwa sebelum saya tahu tentang penggunaan linebreaktoken dalam tata bahasa shell POSIX. Jadi mungkin aman untuk mengatakan bahwa semua shell yang mendukung POSIX akan menerimanya. Saya mendukung pernyataan saya sebagai penafian umum; jika Anda menemukan shell pra-POSIX yang cukup lama, seperti shell Bourne yang sebenarnya atau yang lebih tua, semua taruhan dimatikan.
G-Man