Misalkan saya ingin menjalankan beberapa program secara paralel dan menggabungkan outputnya ke satu pipa:
sh -c '
(echo qqq; echo qqq2; echo qqq3)&
(echo www; echo www2; echo www3)&
(echo eee; echo eee2; echo eee3)&
wait; wait; wait'
Pendekatan shell ini berfungsi dengan baik untuk kasus sederhana ini, tetapi saya berharap akan gagal jika program menghasilkan garis yang lebih banyak dan lebih panjang dengan cara buffered, seperti ini (dibangun):
qqq
qqwww
q2
qqq3www2
wwweee3
eee2
eee3
Salah satu solusi yang saya sarankan untuk digunakan adalah tail -f
:
tail -n +0 -q -f <(echo qqq; echo qqq2; echo qqq3) <(echo www; echo www2; echo www3) <(echo eee; echo eee2; echo eee3)
, tapi ini adalah opsi yang kurang optimal: ini mengeluarkan data dengan lambat, tidak berhenti; Saya melihat output tidak dalam urutan "sleep", tetapi dalam urutan argumen dalam kasus ini:
tail -n +0 -q -f <(sleep 1; echo qqq; sleep 1; echo qqq2; echo qqq3) <(echo www; echo www2; sleep 10; echo www3) <(echo eee; sleep 4; echo eee2; echo eee3) | cat
Saya sudah mengimplementasikan program kecil khusus untuk ini, tetapi percaya bahwa harus ada beberapa cara standar yang baik untuk melakukannya.
Bagaimana cara melakukannya menggunakan alat standar (dan tanpa tail -f
kerugian)?
syslog
...syslog
bukan untuk log, tetapi untuk sesuatu yang menurut kebiasaan dianggap OK?-s
opsi untuk ekor. misalnyatail -f -s .1 file
akan mengurangi penundaan loop menjadi 0,1 detik dari default 1 detik.Jawaban:
GNU Parallel.
Dari catatan rilis tertanggal Agustus 2013:
Sebagai contoh:
parallel --line-buffer <jobs
Dimana
jobs
berisi:short.sh
:long.sh
:Keluaran:
sumber
Solusi yang menerapkan kunci:
Seharusnya ada cara yang lebih cepat untuk membuat kunci daripada menggunakan sistem file.
sumber
Saya tidak dapat memikirkan sesuatu yang sederhana, yang akan membantu Anda, jika dialog Anda terlalu panjang, bahwa satu program akan dikirim untuk tidur sebelum dapat, untuk menyelesaikan menulis baris ke stdout.
Namun, jika baris Anda cukup pendek untuk ditulis seluruhnya sebelum proses beralih, dan masalah Anda adalah, bahwa menghasilkan satu baris membutuhkan waktu sangat lama, Anda dapat buffer output menggunakan read.
Misalnya:
sumber
Anda dapat membuat pipa bernama dengan
mkfifo
, membuang semua output ke pipa bernama, dan membaca secara terpisah dari pipa bernama untuk data yang dikumpulkan:sumber
job1
danjob2
menghasilkan garis panjang (> 4096 byte)? Ini tampaknya dinamai pipa yang sama dengan contoh pertama kode dalam pertanyaan.tee
, yang terdengar persis seperti yang Anda inginkan. Mungkin melihat internalsyslog
atau alat logging lainnya, karena mereka pasti mengumpulkan output dari beberapa tempat menjadi satu file log. Mengunci mungkin merupakan jawaban yang tepat, seperti yang disarankan @emmanual, juga.