Pipa & redirection diutamakan dengan disjuncts, conjuncts dll?

8

Saya tahu tentang prioritas yang relatif mengikat dari operator ';', '&', '&&', atau '||'

http://www.gnu.org/software/bash/manual/bashref.html#Lists

tetapi ketika pipa masuk ke dalam gambar bersama dengan '&&' saya berjuang untuk memahami kekuatan yang mengikat dan baik tersandung pada perintah yang benar atau hanya menyerah.

Apa yang diutamakan yang mengikat dari '|' dan '>' dibandingkan dengan yang di atas?

Contoh di mana saya bingung:

ls _thumbnails/video.mp4.jpg 2>/dev/null 
    && echo "thumbnail already generated. Not regenerating" \
    && exit \
    || ffmpeg_thumbnail_create video.mp4 2>/dev/null \
    && ls _thumbnails/video.mp4.jpg \
    && echo "Thumbnail successfully created" \
    && exit \
    || echo "Thumbnail creation failed" \
    | tee ~/thumbnails.log

Tujuan di atas adalah untuk membuat thumbnail jika dan hanya jika salah satunya belum ada (saya menjalankan cronjob harian). Dan saya tidak suka jumlah besar keluaran ffmpeg ketika tidak ada kesalahan (yang bukan cara Unix). Ada situasi lain juga jadi jangan mulai memberi saya saran yang menggunakan pernyataan terpisah atau opsi khusus untuk program ini. Saya ingin memahami presedensi yang mengikat.

Sridhar Sarnobat
sumber
Sangat membantu - Saya akan menandai ini dengan benar jika itu adalah respons. Hanya satu pertanyaan lagi - bagaimana cara mengubah prioritas? Secara teori saya pikir {... }harus bekerja. Saya mungkin telah mencobanya secara tidak sistematis dan tidak mendapatkan hasil yang diharapkan.
Sridhar Sarnobat

Jawaban:

12

Jawaban singkatnya adalah bahwa <,, >dan varian mereka memiliki prioritas pengikatan tertinggi (pengikatan terketat), diikuti oleh |, diikuti oleh &&dan ||, diikuti oleh ;dan &. Jadi, hanya yang echo "Thumbnail creation failed"disalurkan ke Internet tee.

Jawaban yang sedikit lebih panjang akan menunjukkan bahwa prioritas tertinggi sebenarnya adalah pengelompokan, yang dapat ditunjukkan dengan tanda kurung atau kawat gigi. Sebagai contoh,

A  &&  (B; C)

dan

A  &&  { B; C;}

kira-kira setara dengan

if A
then
    B
    C
fi

Catatan:

  • Tanda kurung memberi Anda sebuah subkulit; yaitu, perintah Bdan Cjalankan dalam proses anak. Oleh karena itu, perintah seperti penugasan variabel atau tidak cd akan berpengaruh pada shell induk. Perintah di kawat gigi dijalankan dalam proses yang sama dengan Aperintah. Oleh karena itu, konstruk brace A && { B; C;}lebih dekat dengan if- then- elsekonstruk.
  • Dalam sintaks brace, harus ada spasi setelah {dan dan ;(atau &, atau baris baru) sebelum }.

Untuk bacaan lebih lanjut, lihat Apa kontrol dan pengalihan operator shell? dan Kapan 'jika' tidak perlu? (terutama jawaban saya).

Untuk bacaan lebih lanjut, lihat halaman manual bash (1) dan spesifikasi / definisi POSIX dari Bahasa Perintah Shell , khususnya Bagian 2.9, Perintah Shell dan Bagian 2.10.2, Aturan Tata Bahasa Shell . Ini adalah upaya untuk memberikan beberapa konteks untuk hal di atas:

  • Hal-hal seperti

    • myVar=42
    • IFS= read a
    • date
    • cd /some/directory
    • ls -laR dir1 dir2
    • cat foo* > /tmp/allfoo
    • ls -laR dir{1,2}
    • find . -type f -name "foo*" -print > /tmp/output 2> /dev/null
    • > newfile
    • [ -f catfood ]
    • exit

    semua dianggap sebagai "perintah sederhana".

  • Hal-hal seperti
      simple_command 1   |   simple_command 2   |   simple_command 3
    adalah "jalur pipa". Tata bahasa membangun blok bangunan dan membangun di atasnya, seperti tipikal untuk tata bahasa formal seperti ini (dan untuk bahasa pemrograman seperti C), sehingga "perintah sederhana" individu dianggap sebagai "pipa", meskipun tidak mengandung sebuah pipa. Tidak masuk akal (semantik) untuk penugasan variabel menjadi komponen pipa, tetapi hal-hal seperti x=1 | od -abatau ls -laR | z=0secara sintaksis valid.
  • Hal-hal seperti
      pipa 1   &&   pipa 2   ||   pipa 3
      disebut "daftar" oleh bash dan "AND-OR daftar" oleh POSIX. Sekali lagi, "jalur pipa" individu atau bahkan "perintah sederhana" individu dianggap sebagai "daftar AND-OR", meskipun tidak mengandung AND atau OR.
    • Ketika Anda sampai pada hal-hal seperti
        DAN-ATAU daftar 1  &   DAN-ATAU daftar 2  ;   DAN-ATAU daftar 3
        nomenklaturnya mulai sedikit tidak konsisten. Bash menyebut "daftar" ini juga; POSIX menyebut mereka "daftar", "daftar majemuk" dan (jarang) "istilah". Sekali lagi, "daftar AND-OR" individu, "pipeline" atau bahkan "perintah sederhana" individu dianggap sebagai "daftar", meskipun tidak mengandung a &atau a ;.
      • Hal-hal seperti
          ( compound_list )
          dan
            {  compound_list ;}
            dan perintah aliran-kontrol ( for,  if- then- else,  while, dll) disebut “perintah senyawa”. 
          • Dalam contoh di atas, mungkin yang paling masuk akal untuk menafsirkan A, Bdan Cmenjadi pipa. Ingat, "saluran pipa" dapat berupa "perintah sederhana" individual; tidak perlu mengandung pipa.

            G-Man Mengatakan 'Reinstate Monica'
            sumber
            1
            Terima kasih untuk penjelasan rinci tentang peran (.. )dan {.. }. Saya telah menyimpulkan dari pengalaman buruk sebelumnya bahwa kurung bulat hanya digunakan dalam konteks "perintah dinamis" (yaitu $(.. )) karena saya hampir tidak bisa membuat mereka melakukan apa pun sejauh yang berkaitan dengan asosiatif.
            Sridhar Sarnobat