Dalam urutan apa perintah pipa dijalankan?


89

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

mengapa tidak menerima jawaban?
törzsmókus

Jawaban:


64

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) apakah psatau grepmulai 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

grep pattern very-large-file | tr a-z A-Z

mulai menampilkan garis yang cocok dalam huruf besar bahkan sebelum grepselesai melintasi file besar.

grep pattern very-large-file | head -n 1

menampilkan baris pertama yang cocok, dan mungkin berhenti memproses dengan baik sebelum grepselesai 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.


7
Dan apa yang keren tentang contoh ini adalah bahwa ketika head mendapatkan satu baris yang dibutuhkannya, maka ia akan berakhir dan ketika Grep memerhatikan hal ini, ia juga akan berakhir tanpa melakukan banyak pekerjaan lebih lanjut tanpa bayaran.
Joe

Saya kira ada semacam penyangga IO tentang pipa ... bagaimana saya tahu itu ukuran dalam byte? Apa yang ingin saya baca untuk mempelajarinya lebih lanjut? :)
n611x007

3
@naxa Sebenarnya ada dua buffer. Ada buffer stdio di dalam grepprogram, dan ada buffer yang dikelola oleh kernel di dalam pipa itu sendiri. Untuk yang terakhir, lihat Seberapa besar penyangga pipa?
Gilles

49

Urutan perintah dijalankan sebenarnya tidak masalah dan tidak dijamin. Mengesampingkan rincian misterius pipe(), fork(), dup()dan execve(), 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.


5
Jawaban yang bagus, tetapi OP tampaknya berpikir proses berjalan berurutan. Anda mungkin membuatnya lebih jelas di sini bahwa prosesnya berjalan bersamaan, dan pipa itu seperti .... pipa antara ember, di mana air mengalir melalui semua pada (sekitar) waktu yang sama.
Keith

Terimakasih atas klarifikasinya. Sumber-sumber yang telah saya baca membuatnya tampak seperti program pipa berjalan secara berurutan, bukan bersamaan.
action_potato

Untuk melihat pengalaman proses yang dimulai dengan cara yang tidak ditentukan coba jalankan ini 1000 kali: echo -na> & 2 | echo b> & 2
Ole Tange

28

Dengan risiko mengalahkan kuda mati, kesalahpahaman tampaknya menjadi itu

    A | B

setara dengan

    A > temporary_file 
    B < temporary_file 
    rm temporary_file

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 Bseperti 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_stringBA


2
Ini menjawab mengapa dan karenanya mendapatkan suara saya.
LIttle Ancient Forest Kami

1

Biasanya Anda menjalankan ini di bawah bash. proses bekerja dan mulai berbarengan, tetapi dijalankan oleh shell secara paralel. Bagaimana itu mungkin?

  1. jika itu bukan perintah terakhir dalam pipa, buat pipa tanpa nama dengan sepasang soket
  2. garpu
  3. pada anak, tetapkan ulang stdin / stdout ke soket jika diperlukan (untuk proses pertama pada pipa stdin tidak dipindahkan, sama untuk proses terakhir dan stdout-nya)
  4. dalam child perintah yang ditentukan EXEC dengan argumen yang menyapu kode shell asli, tetapi membiarkan semua dibuka oleh soket mereka. ID proses anak tidak akan diubah karena ini adalah proses anak yang sama
  5. bersamaan dengan anak tetapi paralel dengan shell utama, lanjutkan ke langkah 1.

sistem tidak menjamin seberapa cepat exec akan dieksekusi dan perintah yang ditentukan dimulai. tidak tergantung pada shell, tetapi sistem. Hal ini karena:

ps auxww| grep ps | cat

sekali tunjukkan grepdan / atau psperintah, dan selanjutnya sekarang. Itu tergantung seberapa cepat kernel benar-benar memulai proses menggunakan fungsi system exec.


1
Eksekusi bersamaan berarti bahwa dua proses atau lebih dieksekusi dalam kerangka waktu yang sama, biasanya dengan semacam ketergantungan di antara mereka. Eksekusi paralel berarti bahwa dua atau lebih proses dieksekusi secara bersamaan (mis. Pada core CPU yang terpisah pada saat yang sama). Paralelisme tidak relevan dengan pertanyaan, juga tidak "seberapa cepat" exec()dieksekusi, tetapi bagaimana exec()panggilan dan eksekusi program dalam pipa disisipkan .
Thomas Nyman
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.