Saya tidak pernah benar-benar berpikir tentang bagaimana shell benar-benar menjalankan perintah pipa. Saya selalu diberitahu bahwa "stdout dari satu program akan disalurkan ke stdin yang lain," sebagai cara berpikir tentang pipa. Jadi secara alami, saya berpikir bahwa dalam kasus katakanlah, A | B, A akan berjalan lebih dulu, kemudian B mendapat stdout dari A, dan menggunakan stdout dari A sebagai inputnya.
Tetapi saya perhatikan bahwa ketika orang mencari proses tertentu dalam ps, mereka akan menyertakan grep -v "grep" di akhir perintah untuk memastikan bahwa grep tidak muncul di hasil akhir. Ini berarti bahwa dalam perintah ps aux | grep "bash" | grep -v "grep", yang berarti bahwa ps tahu bahwa grep sedang berjalan dan oleh karena itu dalam output dari ps. Tetapi jika ps selesai berjalan sebelum outputnya disalurkan ke grep, bagaimana ia tahu bahwa grep berjalan?
flamingtoast@FTOAST-UBUNTU: ~$ ps | grep ".*"
PID TTY TIME CMD
3773 pts/0 00:00:00 bash
3784 pts/0 00:00:00 ps
3785 pts/0 00:00:00 grep
Jawaban:
Perintah pipa dijalankan secara bersamaan. Ketika Anda berlari
ps | grep …
, itu adalah keberuntungan undian (atau masalah detail kerja shell dikombinasikan dengan penjadwal fine-tuning jauh di dalam usus kernel) apakahps
ataugrep
mulai pertama, dan dalam hal apapun mereka terus jalankan secara bersamaan.Ini sangat umum digunakan untuk memungkinkan program kedua memproses data saat keluar dari program pertama, sebelum program pertama menyelesaikan operasinya. Sebagai contoh
mulai menampilkan garis yang cocok dalam huruf besar bahkan sebelum
grep
selesai melintasi file besar.menampilkan baris pertama yang cocok, dan mungkin berhenti memproses dengan baik sebelum
grep
selesai membaca file inputnya.Jika Anda membaca suatu tempat bahwa program pipa dijalankan secara berurutan, larilah dari dokumen ini. Program perpipaan berjalan secara bersamaan dan selalu ada.
sumber
grep
program, dan ada buffer yang dikelola oleh kernel di dalam pipa itu sendiri. Untuk yang terakhir, lihat Seberapa besar penyangga pipa?Urutan perintah dijalankan sebenarnya tidak masalah dan tidak dijamin. Mengesampingkan rincian misterius
pipe()
,fork()
,dup()
danexecve()
, shell pertama menciptakan pipa, saluran untuk data yang akan mengalir antara proses, dan kemudian menciptakan proses dengan ujung pipa yang terhubung ke mereka. Proses pertama yang dijalankan dapat memblokir menunggu input dari proses kedua, atau memblokir menunggu proses kedua untuk mulai membaca data dari pipa. Menunggu ini bisa lama dan sewenang-wenang tidak masalah. Apapun urutan proses yang dijalankan, data akhirnya ditransfer dan semuanya berfungsi.sumber
Dengan risiko mengalahkan kuda mati, kesalahpahaman tampaknya menjadi itu
setara dengan
Tapi, ketika Unix dibuat dan anak-anak mengendarai dinosaurus ke sekolah, cakramnya sangat kecil, dan itu biasa bagi perintah yang agak jinak untuk menggunakan semua ruang kosong dalam sistem file. Jika
B
seperti itu , hasil akhir dari pipa bisa jauh lebih kecil dari file perantara itu. Oleh karena itu, pipa dikembangkan, bukan sebagai singkatan untuk “lari A pertama, dan kemudian jalankan B dengan masukan dari A ‘s output”model, tetapi sebagai cara untuk mengeksekusi bersamaan dengan dan menghilangkan kebutuhan untuk menyimpan file menengah pada disk.grep some_very_obscure_string
B
A
sumber
Biasanya Anda menjalankan ini di bawah bash. proses bekerja dan mulai berbarengan, tetapi dijalankan oleh shell secara paralel. Bagaimana itu mungkin?
sistem tidak menjamin seberapa cepat exec akan dieksekusi dan perintah yang ditentukan dimulai. tidak tergantung pada shell, tetapi sistem. Hal ini karena:
sekali tunjukkan
grep
dan / ataups
perintah, dan selanjutnya sekarang. Itu tergantung seberapa cepat kernel benar-benar memulai proses menggunakan fungsi system exec.sumber
exec()
dieksekusi, tetapi bagaimanaexec()
panggilan dan eksekusi program dalam pipa disisipkan .