Saya memiliki tiga jenis data yang dalam format berbeda; untuk setiap tipe data, ada skrip Python yang mengubahnya menjadi satu format tunggal.
Skrip Python ini lambat dan terikat CPU (ke satu inti pada mesin multi-inti), jadi saya ingin menjalankan tiga contoh - satu untuk setiap tipe data - dan menggabungkan output mereka untuk meneruskannya sort
. Pada dasarnya, setara dengan ini:
{ ./handle_1.py; ./handle_2.py; ./handle_3.py } | sort -n
Tetapi dengan tiga skrip berjalan secara paralel.
Saya menemukan pertanyaan ini di mana GNU split
digunakan untuk membulatkan beberapa aliran stdout antara n contoh skrip yang menangani aliran.
Dari halaman manual split:
-n, --number=CHUNKS
generate CHUNKS output files. See below
CHUNKS may be:
N split into N files based on size of input
K/N output Kth of N to stdout
l/N split into N files without splitting lines
l/K/N output Kth of N to stdout without splitting lines
r/N like 'l' but use round robin distributio
Jadi r/N
perintah itu menyiratkan " tanpa garis pemisah ".
Berdasarkan ini, sepertinya solusi berikut harus layak:
split -n r/3 -u --filter="./choose_script" << EOF
> 1
> 2
> 3
> EOF
Di mana choose_script
ini:
#!/bin/bash
{ read x; ./handle_$x.py; }
Sayangnya, saya melihat beberapa jalinan garis - dan banyak baris baru yang seharusnya tidak ada di sana.
Misalnya, jika saya mengganti skrip Python saya dengan beberapa skrip bash sederhana yang melakukan ini:
#!/bin/bash
# ./handle_1.sh
while true; echo "1-$RANDOM"; done;
.
#!/bin/bash
# ./handle_2.sh
while true; echo "2-$RANDOM"; done;
.
#!/bin/bash
# ./handle_3.sh
while true; echo "3-$RANDOM"; done;
Saya melihat output ini:
1-8394
2-11238
2-22757
1-723
2-6669
3-3690
2-892
2-312511-24152
2-9317
3-5981
Ini menjengkelkan - berdasarkan pada ekstrak halaman manual yang saya tempel di atas, itu harus menjaga integritas garis.
Jelas itu berfungsi jika saya menghapus -u
argumen, tetapi kemudian buffered dan saya akan kehabisan memori karena buffer output semua kecuali satu skrip.
Jika ada yang memiliki wawasan di sini, itu akan sangat dihargai. Saya keluar dari kedalaman saya di sini.
coproc
builtin di bash, meskipun saya tidak benar-benar melihat bagaimana itu berlaku.job1.py > file1 & job2.py > file 2 & job3.py > file3 ; wait ; sort -n file1 file2 file3
?Jawaban:
Coba gunakan opsi -u paralel GNU.
Ini menjalankannya secara paralel, tanpa buffering keseluruhan proses.
sumber
X
diIX
mengatakan-I
bahwa X akan bendera untuk mengganti, atau itu menerapkan-X
bendera, yang tampaknya juga memiliki makna yang relevan?parallel -u -X ./handle_{}.sh ::: "1" "2" "3"
:, dan sayangnya saya masih melihat beberapa output mangling.parallel -u ./handle_{}.sh
, tetapi saya lebih suka mengubahnya, karena kawat gigi juga memiliki arti menggabungkan perintah bersama (seperti dalam pertanyaan Anda).Mencoba:
Jika
handle_1.py
mengambil nama file:Anda tidak ingin output tercampur, jadi jangan gunakan -u.
Jika Anda ingin menjaga urutan (jadi semua keluaran handle_1 adalah sebelum handle_2 dan dengan demikian Anda mungkin bisa menghindari penyortiran):
Jika Anda tetap menginginkannya diurutkan, Anda dapat memparalelkan sortir dan memanfaatkan
sort -m
:Set $ TMPDIR ke dir yang cukup besar untuk menampung output.
sumber
Mungkin saya kehilangan sesuatu, tetapi tidak bisakah Anda melakukannya:
Jika Anda ingin garis-garis dari setiap proses tidak diselingi, lebih mudah mungkin untuk memastikan bahwa proses itu sendiri menuliskannya secara penuh dan mungkin menonaktifkan buffering output karena
write
s ke pipa dijamin atom selama mereka tidak lebih besar dariPIPE_BUF
. Misalnya, Anda bisa memastikan itu tidak menggunakan buffering à lastdio
dan panggilanfflush
atau apa pun yang setarapython
setelah satu atau beberapa baris telah ditulis.Jika Anda tidak dapat mengubah skrip python, Anda dapat melakukan:
(dengan GNU grep) atau:
(Lihat catatan dalam komentar di bawah ini jika apa perintah output bukan teks)
Dan lakukan:
Pilihan lain untuk menghindari 3
lb
proses tersebut adalah memiliki tiga pipa ke satu perintah yang menggunakanselect
/poll
untuk melihat dari mana ada beberapa output yang berasal dan mengumpankannya kesort
berbasis garis, tetapi membutuhkan sedikit pemrograman.sumber
wait
di sana, saya pikir.sort -n
akan tetap sampai semua program yang memiliki fd terbuka di atasnya telah keluar.Jawaban Flowbok adalah solusi yang benar. Anehnya, output GNU
parallel
akan hancur jika itu output langsung ke file - tetapi tidak jika pergi ke tty.Untungnya,
script -c
tersedia untuk meniru tty.Masih ada tiga skrip:
.
.
Lalu ada file yang merangkum panggilan ke paralel:
Dan saya menyebutnya seperti ini:
Garis-garis dalam output dicampur baris-demi-baris antara output dari skrip yang berbeda, tetapi mereka tidak mendapatkan rusak atau disisipkan pada baris yang diberikan.
Perilaku aneh dari
parallel
- Saya dapat mengajukan laporan bug.sumber