Saya baru saja menjalankan beberapa perintah di terminal dan saya mulai bertanya-tanya, apakah Unix / Linux mengambil jalan pintas saat menjalankan perintah pipa?
Sebagai contoh, katakanlah saya memiliki file dengan satu juta baris, 10 di antaranya berisi hello world
. Jika Anda menjalankan perintah grep "hello world" file | head
apakah perintah pertama berhenti segera setelah ia menemukan 10 baris, atau apakah ia terus mencari seluruh file terlebih dahulu?
command-line
pipe
utilities
efficiency
DisgruntledGoat
sumber
sumber
-m
argumen.Jawaban:
Semacam. Shell tidak tahu perintah apa yang sedang Anda jalankan, ia hanya menghubungkan output dari satu ke input yang lain.
Jika
grep
menemukan lebih dari 10 baris yang mengatakan "hello world" makahead
akan memiliki semua 10 baris yang diinginkan, dan tutup pipa. Ini akan menyebabkangrep
terbunuh dengan SIGPIPE, sehingga tidak perlu melanjutkan pemindaian file yang sangat besar.sumber
grep
akan terus mengirim output menjadi kosong, mirip dengan/dev/null
Ketika suatu program mencoba menulis ke sebuah pipa dan tidak ada proses membaca dari pipa itu, maka program penulis menerima sinyal SIGPIPE . Tindakan default ketika sebuah program menerima SIGPIPE adalah untuk menghentikan program. Suatu program dapat memilih untuk mengabaikan sinyal SIGPIPE, dalam hal ini penulisan mengembalikan kesalahan (
EPIPE
).Dalam contoh Anda, inilah garis waktu dari apa yang terjadi:
grep
danhead
perintah start up secara paralel.grep
membaca beberapa input, mulai memprosesnya.grep
menghasilkan potongan output pertama.head
membaca potongan pertama itu dan menulisnya.grep
mungkin berakhir terlebih dahulu), akhirnyahead
akan dicetak jumlah garis yang diinginkan. Pada titik ini,head
keluar.grep
danhead
proses,grep
mungkin telah mengumpulkan beberapa data dan belum mencetaknya. Pada saathead
keluar,grep
mungkin sedang membaca input atau melakukan pemrosesan internal, dalam hal ini akan terus melakukannya.grep
akan menulis data yang sedang diproses. Pada saat itu, ia akan menerima SIGPIPE dan mati.Kemungkinan
grep
akan memproses sedikit lebih banyak input daripada yang diperlukan, tetapi biasanya hanya beberapa kilobyte:head
biasanya membaca dalam potongan beberapa kilobyte (karena itu lebih efisien daripada mengeluarkanread
panggilan sistem untuk setiap byte - perilaku ini disebut buffering), sehingga sisa potongan terakhir setelah baris terakhir yang diinginkan dibuang.grep
mungkin telah mengakumulasikan beberapa data yang siap menjadi potongan keluaran (buffering lagi). Ini akan menerima SIGPIPE ketika mencoba untuk menyiram buffer outputnya.Semua dalam semua sistem dirancang dengan tepat sehingga utilitas penyaringan secara alami berperilaku efisien. Program yang perlu terus berjalan ketika saluran output mereka mati harus mengambil langkah mengabaikan sinyal SIGPIPE.
sumber
Sortof, pipeline bekerja seperti ini: pertama mengeksekusi perintah pertama dan kemudian perintah kedua dalam kasus Anda.
Artinya, mari kita
A|B
menjadi perintah yang diberikan. Maka tidak pasti apakah dimulaiA
atau tidakB
. Mereka mungkin mulai pada waktu yang sama persis jika ada beberapa CPU. Sebuah pipa dapat menampung jumlah data yang tidak ditentukan tetapi terbatas.Jika B mencoba membaca dari pipa, tetapi tidak ada data yang tersedia,
B
akan menunggu sampai data tiba. JikaB
sedang membaca dari disk,B
mungkin memiliki masalah yang sama dan perlu menunggu sampai disk selesai dibaca. Analogi yang lebih dekat adalah membaca dari keyboard. Di sana,B
perlu menunggu pengguna mengetik. Tetapi dalam semua kasus ini, B telah memulai operasi "baca" dan harus menunggu sampai selesai. Tetapi jikaB
suatu perintah sedemikian rupa sehingga hanya membutuhkan sebagian outputA
kemudian setelah titik tertentuB
di mana level input tercapai,A
akan dibunuh oleh SIGPIPEJika
A
mencoba menulis ke pipa dan pipa penuh,A
harus menunggu beberapa ruang di pipa menjadi bebas.A
bisa memiliki masalah yang sama jika sedang menulis ke terminal. Terminal memiliki kontrol aliran dan dapat memoderasi laju data. Bagaimanapun, untukA
, ia telah memulai operasi "tulis" dan akan menunggu sampai operasi penulisan selesai.A
danB
berperilaku sebagai proses bersama, meskipun tidak semua proses bersama akan berkomunikasi dengan pipa. Tidak ada yang memegang kendali penuh atas yang lain.sumber
head
Keluar), sinyal SIGPIPE muncul dalam program dan perilaku defaultnya adalah untuk keluar.grep
tidak memiliki kontrol langsung terhadap pipa (itu hanya menerima data), dan pipa tidak memiliki kontrol langsunggrep
(hanya mengirim data) ...Apa
grep
, atau program lain apa pun, sepenuhnya tergantung pada logika internal program tersebut. Jika Anda memberi tahugrep
melalui opsi baris perintah untuk membuat keluar awal ketika ditemukan , maka itu akan, jika tidak maka akan terhenti di bagian paling akhir file mencari pola ...Terminal juga cukup terputus dari cara kerja internal
grep
danshell
tindakan perpipaan ... Terminal pada dasarnya hanya landasan peluncuran, dan tampilan keluaran ...sumber