Saat bereksperimen dengan pengalihan output dan penggantian proses, saya menemukan perintah berikut dan hasil yang dihasilkan:
me @ elem: ~ $ echo foo>> (cat); bilah gema batang saya @ elem: ~ $ foo
(Ya, baris baru yang kosong pada akhirnya memang disengaja.)
Jadi bash echo bar, cetak prompt saya yang biasa, echo foo, echo a newline, dan tinggalkan kursor saya di sana. Jika saya menekan enter lagi, itu akan mencetak prompt saya pada baris baru dan membiarkan kursor mengikutinya (seperti yang diharapkan ketika seseorang menekan enter pada baris perintah kosong).
Saya mengharapkannya untuk menulis foo ke deskriptor file, cat membacanya dan echo foo, bilah gema gema kedua, dan kemudian kembali ke command prompt. Tapi jelas bukan itu masalahnya.
Bisakah seseorang tolong jelaskan apa yang terjadi?
bash
shell
process-substitution
concurrency
Stanley Yu
sumber
sumber
Jawaban:
Anda mungkin melihat
foo
ditampilkan sebelumbar
, setelahbar
, atau bahkan setelah prompt, tergantung pada waktu. Tambahkan sedikit keterlambatan untuk mendapatkan waktu yang konsisten:bar
muncul segera, lalufoo
setelah satu detik, lalu prompt berikutnya setelah detik lainnya.Apa yang terjadi adalah bahwa bash menjalankan proses penggantian di latar belakang.
sleep 1; cat
, dan mengatur pipa untuk itu.echo foo
. Karena ini tidak mengisi buffer pipa,echo
perintah berakhir tanpa pemblokiran.echo bar
.sleep 2
.sleep 1
.sleep 1
kembali dalam proses. Subproses mulai dijalankancat
.cat
menyalin inputnya ke outputnya (yang ditampilkan di layar) dan kembali.sleep 2
kembali. Proses shell utama selesai dijalankan dan Anda bisa melihat prompt berikutnya.sumber
Anda tidak perlu proses substitusi untuk mendapatkan efek itu. Coba ini:
Anda akan mendapatkan hasil yang sama (tanpa
bar
; Saya akan meninggalkan itu sebagai latihan) dan untuk alasan yang sama. Dalam kedua kasus,cat
dimulai sebagai tugas latar belakang. Dalam baris saya di sini, itu eksplisit. Dalam kasus substitusi proses, ini juga eksplisit - ini adalah proses terpisah yang dilampirkan ke deskriptor file nama - tetapi mungkin tidak sejelas itu.Proses anak tidak harus berakhir sebelum
bash
mencetak prompt berikutnya. Dan karena outputnya di-buffer, ia tidak mengeluarkan apa-apa sampai ia berakhir. Pada saat itu, bash baru saja dicetak$
pada stderr, dan sekarang proses latar belakang keluar setelah pencetakanfoo
dan baris baru.sumber