Bisakah Anda menguraikan tindakan secara berbeda bagian dari pertanyaan Anda?
devnull
Anda memiliki kontrol terbatas atas seberapa jauh prog2kemajuan terjadi ketika prog1keluar, karena buffering internal yang digunakan untuk mengimplementasikan pipa dan bagaimana prog1dan prog2dijadwalkan.
chepner
Lihat juga [Dalam urutan apa perintah pipa dijalankan?] (Unix.stackexchange.com/q/37508)
DK Bose
Jawaban:
4
Jawaban umum adalah tidak. Dimungkinkan untuk prog2keluar prog1bahkan sebelum mulai (jelas itu tidak dapat terjadi jika prog2benar-benar membaca beberapa input, yang Anda harapkan akan dilakukan jika Anda menggunakannya dalam pipa). Sangat mungkin untuk prog2keluar sebelum prog1; ini terjadi misalnya ketika prog2program pencarian yang keluar segera setelah menemukan kecocokan, dalam hal ini prog1mungkin belum selesai menghasilkan semua data.
Tidak ada cara langsung untuk prog2mengambil status keluar prog1atau bahkan untuk mengetahui yang prog1telah keluar. Yang prog2bisa diketahui hanyalah bahwa prog1ujung pipa itu sudah ditutup, yang bisa dilakukan tanpa sekarat.
Jika Anda ingin mendapatkan status keluar prog1dari prog2, ada dua metode umum: Anda dapat menulisnya ke file, atau Anda dapat mengirimkannya melalui pipa. Mengirim status output sebagai baris terakhir dari data yang disalurkan adalah suatu kemungkinan. Anda harus memastikan untuk tidak memproses baris terakhir sampai Anda tahu bahwa itu adalah baris terakhir, yaitu sampai Anda mencoba membaca baris berikutnya.
{ prog1; echo $?;}|…
Berikut adalah contoh di mana sisi kanan adalah filter teks yang mewarnai setiap baris yang mengandung kata "error" merah. Jika sisi kiri gagal, sisi kanan keluar dengan status yang sama.
{ prog1; echo $?;}| awk '
NR != 1 {
if (line ~ /[Ee][Rr][Rr][Oo][Rr]/) print "\033[31m" line "\033[0m";
else print line;
}
{line = $0}
END {exit($0)}
'
Saya mencoba { command; echo ${PIPESTATUS[@]}; } | sort | ...agar status keluar lebih dulu di arus. Semuanya sangat menarik!
@ illuminÉ Itu hanya akan berfungsi jika ${PIPESTATUS[@]}diurutkan sebelum apa pun di output dari command. Jika commandmencetak sekelompok angka, atau jika dapat mencetak teks sewenang-wenang, Anda dalam kesulitan: Anda tidak akan dapat membedakan outputnya dari baris status.
Gilles 'SANGAT berhenti menjadi jahat'
Terima kasih, memang hanya berhasil menyortir status sukses ke atas jika perintah tidak mengandung 0 pada outputnya lol. Tgif / dtk.
2
Meskipun Anda bisa dalam beberapa kasus khusus (lihat jawaban lain) Anda tidak bisa dalam setiap kasus. Beberapa program filter hanya akan terus berjalan, sementara yang lain akan menahan semua output, lepaskan dalam satu ledakan, dan kemudian keluar.
Sebagai contoh program "terus berjalan", grepakan server, seperti yang akan tail -f /var/log/some_log_file. Penggunaan sortdalam pipa menyebabkan "kios", karena sortakan mengumpulkan input sampai pipa di depannya menutup. Menggunakan xargsmenambah kerumitan lebih lanjut: apakah program dimulai oleh xargs(mungkin memulai banyak contoh) bagian dari pipa atau tidak?
-1 karena Anda di mana dipilih untuk merasionalisasi jawaban yang salah.
ctrl-alt-delor
@ Richard Huh? Jawaban Bruce benar (meskipun paragraf kedua sedikit membingungkan).
Gilles 'SANGAT berhenti menjadi jahat'
1
Jawabannya: Tidak secara langsung.
@terdon telah menggambarkan bahwa kode keluar dari perintah sebelumnya di dalam pipa harus dikirim sebagai parameter eksplisit ke perintah berikutnya.
Ingat bahwa pipa hanyalah pemetaan dari STDOUT perintah sebelumnya ke STDIN perintah berikutnya; kode keluar tidak dikeluarkan ke STDOUT (atau STDERR).
-1 karena Anda di mana dipilih untuk mengutip jawaban yang salah, dan tidak banyak bicara.
ctrl-alt-delor
@ Richard cukup adil ... Seharusnya aku memeriksa ulang ... itulah yang terjadi jika aku memaksakan diriku untuk menjawab pertanyaan ketika sangat lelah ...
pepoluan
1
Semua proses, dalam pipa, dimulai sebelum keluar. Oleh karena itu prog2bisa mendapatkan info ini setelah dimulai, itu juga harus menunda pemrosesan sampai prog1keluar, ini bisa menunda pipa. Tampaknya ada masalah mendasar dalam melakukan apa yang Anda minta, bukan batasan OS.
Anda mungkin perlu mempertimbangkan file sementara, atau meletakkan hasilnya dalam variabel.
Contoh untuk sejumlah kecil data, menggunakan variabel.
tmp=$(prog1)if test "z$PIPESTATUS"=="z0"then…else…fi
Ada celah dalam alasan Anda. prog2dimulai sebelum prog1selesai secara umum, tetapi mungkin ada cara untuk menerima status output dari prog1saat sedang berjalan.
prog2
kemajuan terjadi ketikaprog1
keluar, karena buffering internal yang digunakan untuk mengimplementasikan pipa dan bagaimanaprog1
danprog2
dijadwalkan.Jawaban:
Jawaban umum adalah tidak. Dimungkinkan untuk
prog2
keluarprog1
bahkan sebelum mulai (jelas itu tidak dapat terjadi jikaprog2
benar-benar membaca beberapa input, yang Anda harapkan akan dilakukan jika Anda menggunakannya dalam pipa). Sangat mungkin untukprog2
keluar sebelumprog1
; ini terjadi misalnya ketikaprog2
program pencarian yang keluar segera setelah menemukan kecocokan, dalam hal iniprog1
mungkin belum selesai menghasilkan semua data.Tidak ada cara langsung untuk
prog2
mengambil status keluarprog1
atau bahkan untuk mengetahui yangprog1
telah keluar. Yangprog2
bisa diketahui hanyalah bahwaprog1
ujung pipa itu sudah ditutup, yang bisa dilakukan tanpa sekarat.Jika Anda ingin mendapatkan status keluar
prog1
dariprog2
, ada dua metode umum: Anda dapat menulisnya ke file, atau Anda dapat mengirimkannya melalui pipa. Mengirim status output sebagai baris terakhir dari data yang disalurkan adalah suatu kemungkinan. Anda harus memastikan untuk tidak memproses baris terakhir sampai Anda tahu bahwa itu adalah baris terakhir, yaitu sampai Anda mencoba membaca baris berikutnya.Berikut adalah contoh di mana sisi kanan adalah filter teks yang mewarnai setiap baris yang mengandung kata "error" merah. Jika sisi kiri gagal, sisi kanan keluar dengan status yang sama.
sumber
{ command; echo ${PIPESTATUS[@]}; } | sort | ...
agar status keluar lebih dulu di arus. Semuanya sangat menarik!${PIPESTATUS[@]}
diurutkan sebelum apa pun di output daricommand
. Jikacommand
mencetak sekelompok angka, atau jika dapat mencetak teks sewenang-wenang, Anda dalam kesulitan: Anda tidak akan dapat membedakan outputnya dari baris status.Meskipun Anda bisa dalam beberapa kasus khusus (lihat jawaban lain) Anda tidak bisa dalam setiap kasus. Beberapa program filter hanya akan terus berjalan, sementara yang lain akan menahan semua output, lepaskan dalam satu ledakan, dan kemudian keluar.
Sebagai contoh program "terus berjalan",
grep
akan server, seperti yang akantail -f /var/log/some_log_file
. Penggunaansort
dalam pipa menyebabkan "kios", karenasort
akan mengumpulkan input sampai pipa di depannya menutup. Menggunakanxargs
menambah kerumitan lebih lanjut: apakah program dimulai olehxargs
(mungkin memulai banyak contoh) bagian dari pipa atau tidak?sumber
Jawabannya: Tidak secara langsung.
@terdon telah menggambarkan bahwa kode keluar dari perintah sebelumnya di dalam pipa harus dikirim sebagai parameter eksplisit ke perintah berikutnya.
Ingat bahwa pipa hanyalah pemetaan dari STDOUT perintah sebelumnya ke STDIN perintah berikutnya; kode keluar tidak dikeluarkan ke STDOUT (atau STDERR).
sumber
Semua proses, dalam pipa, dimulai sebelum keluar. Oleh karena itu
prog2
bisa mendapatkan info ini setelah dimulai, itu juga harus menunda pemrosesan sampaiprog1
keluar, ini bisa menunda pipa. Tampaknya ada masalah mendasar dalam melakukan apa yang Anda minta, bukan batasan OS.Anda mungkin perlu mempertimbangkan file sementara, atau meletakkan hasilnya dalam variabel.
Contoh untuk sejumlah kecil data, menggunakan variabel.
sumber
prog2
dimulai sebelumprog1
selesai secara umum, tetapi mungkin ada cara untuk menerima status output dariprog1
saat sedang berjalan.Untuk menyelesaikan jawaban Gilles ,
adalah sebuah pendekatan.
prog2
bisa juga/tmp/prog1.status
, atau/tmp/prog1.status
secara berkala sambil membaca input standar.sumber