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.
sumber
{
...}
harus bekerja. Saya mungkin telah mencobanya secara tidak sistematis dan tidak mendapatkan hasil yang diharapkan.Jawaban:
Jawaban singkatnya adalah bahwa
<
,,>
dan varian mereka memiliki prioritas pengikatan tertinggi (pengikatan terketat), diikuti oleh|
, diikuti oleh&&
dan||
, diikuti oleh;
dan&
. Jadi, hanya yangecho "Thumbnail creation failed"
disalurkan ke Internettee
.Jawaban yang sedikit lebih panjang akan menunjukkan bahwa prioritas tertinggi sebenarnya adalah pengelompokan, yang dapat ditunjukkan dengan tanda kurung atau kawat gigi. Sebagai contoh,
dan
kira-kira setara dengan
Catatan:
B
danC
jalankan dalam proses anak. Oleh karena itu, perintah seperti penugasan variabel atau tidakcd
akan berpengaruh pada shell induk. Perintah di kawat gigi dijalankan dalam proses yang sama denganA
perintah. Oleh karena itu, konstruk braceA && { B; C;}
lebih dekat denganif
-then
-else
konstruk.{
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".
x=1 | od -ab
atauls -laR | z=0
secara sintaksis valid.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.
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;
.dan
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
,B
danC
menjadi pipa. Ingat, "saluran pipa" dapat berupa "perintah sederhana" individual; tidak perlu mengandung pipa.sumber
(
..)
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.