Menurut ini , menempatkan daftar perintah antara kurung kurawal menyebabkan daftar dieksekusi dalam konteks shell saat ini. Tidak ada subkulit yang dibuat .
Menggunakan ps
untuk melihat ini dalam aksi
Ini adalah hierarki proses untuk pipa proses yang dieksekusi langsung pada baris perintah. 4398 adalah PID untuk shell login:
sleep 2 | ps -H;
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29696 pts/23 00:00:00 sleep
29697 pts/23 00:00:00 ps
Sekarang ikuti hierarki proses untuk pipa proses antara kurung kurawal yang dieksekusi langsung pada baris perintah. 4398 adalah PID untuk shell login. Ini mirip dengan hierarki di atas yang membuktikan bahwa semuanya dijalankan dalam konteks shell saat ini :
{ sleep 2 | ps -H; }
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29588 pts/23 00:00:00 sleep
29589 pts/23 00:00:00 ps
Sekarang, ini adalah hierarki proses ketika sleep
pipa itu sendiri ditempatkan di dalam kurung kurawal (jadi ada dua level kurung kurawal)
{ { sleep 2; } | ps -H; }
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29869 pts/23 00:00:00 bash
29871 pts/23 00:00:00 sleep
29870 pts/23 00:00:00 ps
Mengapa bash
harus membuat subkulit untuk berjalan sleep
dalam kasus ke-3 ketika dokumentasi menyatakan bahwa perintah antara kurung kurawal dieksekusi dalam konteks shell saat ini?
{ sleep 2 | command ps -H; }
Jawaban:
Dalam sebuah pipeline, semua perintah berjalan secara bersamaan (dengan stdout / stdin dihubungkan oleh pipa) sehingga dalam proses yang berbeda.
Di
Ketiga perintah dijalankan dalam proses yang berbeda, jadi setidaknya dua di antaranya harus dijalankan dalam proses anak. Beberapa shell menjalankan salah satu dari mereka dalam proses shell saat ini (jika builtin suka
read
atau jika pipeline adalah perintah terakhir dari skrip), tetapibash
menjalankan semuanya dalam proses terpisah mereka sendiri (kecuali denganlastpipe
opsi dibash
versi terbaru dan dalam beberapa kondisi tertentu ).{...}
perintah grup. Jika grup itu adalah bagian dari sebuah pipeline, ia harus dijalankan dalam proses terpisah seperti perintah sederhana.Di:
Kami membutuhkan shell untuk mengevaluasi itu
a; b "$?"
adalah proses yang terpisah, jadi kami membutuhkan subkulit. Shell dapat dioptimalkan dengan tidak forkingb
karena itu perintah terakhir yang dijalankan dalam grup itu. Beberapa kerang melakukannya, tetapi ternyata tidakbash
.sumber
bash -c "sleep 112345 | cat | cat "
saya hanya melihat satu bash dibuat dan kemudian 3 anak untuk itu tanpa sub bash lain interleaving.a; b "$?"
? Apakah benar-benar ada kebutuhan mendasar untuk sebuah subsheel, atau mungkin itu adalah keputusan desain / implementasi di bash?eval
), tetapi evaluasi (jalankan perintah pertama, tunggu, jalankan yang kedua) adalah dilakukan pada anak, yang stdout terhubung ke pipa.{ sleep 2 | ps -H; }
bash induk melihatsleep 2
yang membutuhkan garpu / exec. Tetapi dalam{ { sleep 2; } | ps -H; }
bash induk melihat{ sleep 2; }
dengan kata lain, beberapa kode bash. Sepertinya orang tua dapat menangani fork / exec untuksleep 2
tetapi memunculkan bash baru secara rekursif untuk menangani kode bash yang ditemui. Itu pemahaman saya, apakah masuk akal?Bersarang di kurung kurawal akan menunjukkan bahwa Anda sedang membuat tingkat tambahan pelingkupan yang membutuhkan sub-shell baru untuk dipanggil. Anda dapat melihat efek ini dengan salinan Bash ke-2 di
ps -H
output Anda .Hanya proses yang ditetapkan pada kurung kurawal tingkat pertama yang dijalankan dalam ruang lingkup Bash shell asli. Setiap kurung kurawal bersarang akan berjalan di cangkang Bash miliknya sendiri.
Contoh
Mengambil
| ps -H
keluar dari campuran supaya kita bisa melihat kurung kurawal bersarang, kita bisa larips auxf | less
di shell lain.Tapi tunggu, masih ada lagi!
Jika Anda mengambil pipa dan menggunakan bentuk perintah ini, kami melihat apa yang sebenarnya Anda harapkan:
Sekarang di jendela arloji yang dihasilkan, kami mendapatkan pembaruan setiap 2 detik dari apa yang terjadi:
Inilah yang pertama
sleep 10
:Inilah yang kedua
sleep 10
:Inilah yang ketiga
sleep 10
:Perhatikan ketiga tidur meskipun dilakukan pada tingkat yang berbeda dari kurung kurawal tetap pada PID 5676 dari Bash. Jadi saya percaya masalah Anda disebabkan oleh penggunaan
| ps -H
.Kesimpulan
Penggunaan
| ps -H
(yaitu pipa) menyebabkan sub-shell tambahan, jadi jangan gunakan metode itu ketika mencoba untuk menginterogasi apa yang terjadi.sumber
Saya akan memposting hasil tes saya, yang membawa saya pada kesimpulan bahwa bash membuat sub-shell untuk perintah grup jika dan hanya jika itu adalah bagian dari pipeline, itu sama seperti jika seseorang akan memanggil beberapa fungsi yang juga akan dipanggil di sub-shell.
sumber