Saya kadang-kadang menjalankan xargs
pekerjaan panjang dalam semalam dan sangat menjengkelkan untuk menemukan di pagi hari yang xargs
meninggal di suatu tempat di tengah, misalnya karena kesalahan segmentasi dalam satu kasus khusus, seperti yang terjadi malam ini.
Jika bahkan satu xargs
anak terbunuh, itu tidak memproses input lagi:
Konsol 1:
[09:35:48] % seq 40 | xargs -i --max-procs=4 bash -c 'sleep 10; date +"%H:%M:%S {}";'
xargs: bash: terminated by signal 15
09:35:58 3
09:35:58 4
09:35:58 2
<Exit with code 125>
Konsol 2:
[09:35:54] kill 5601
Dapatkah saya mencegah xargs
berhenti memproses input lagi setelah proses anak meninggal dan melanjutkan pemrosesan?
xargs
versi 4.4.2debian wheezy
dan sepertinya setiap hal berjalan dengan baik bahkan jika saya membunuhsleep
proses tertentu . Versi apaxargs
yang Anda gunakan? mungkin mereka telah memperbaiki masalah ini dalam versi terbaru.xargs ... bash -c '...;exit 0'
atau bahkanxargs ... bash -c '... || echo erk'
parallel -j 1
ini adalah solusi hack yang mungkin.Jawaban:
Tidak, kamu tidak bisa. Dari
xargs
sumber di savannah.gnu.org :Tidak ada bendera di sekitar pemeriksaan itu, atau di sekitar fungsi yang memanggilnya. Tampaknya memang terkait dengan procs maks, yang saya kira masuk akal: jika Anda mengatur procs maks cukup tinggi, tidak akan repot memeriksa sampai mencapai batas, yang Anda mungkin tidak akan pernah.
Solusi yang lebih baik untuk apa yang Anda coba lakukan mungkin menggunakan GNU Make :
Kemudian:
akan memiliki efek yang sama, dan memberi Anda kontrol yang jauh lebih baik.
sumber
Tampaknya salah satu bahasa sehari-hari yang paling jelas hanya disinggung oleh proposal lain.
Artinya, Anda dapat menggunakan yang berikut ini:
untuk "memaksa kesuksesan".
Catatan, ini sejalan dengan proposal oleh lornix (tidak banyak kata).
Bagaimanapun, karena ini secara efektif mengabaikan status keluar proses yang sebenarnya, saya akan memastikan Anda mempertimbangkan entah bagaimana menyimpan status sub-proses untuk analisis post-mortem. Misalnya:
Di
true
sini agak berlebihan dan jadi ini mungkin lebih baik ditulis sebagai:Karena kami mungkin ingin tahu kapan file 'gagal' tidak dapat disentuh. Dengan kata lain, kita tidak lagi mengabaikan kegagalan, kita memperhatikan dan melanjutkan.
Dan, setelah mempertimbangkan sifat rekursif dari masalah ini, mungkin kita melihat persis mengapa xargs tidak membuat kegagalan kegagalan menjadi mudah. Karena itu tidak pernah merupakan ide yang baik - Anda harus meningkatkan penanganan kesalahan dalam proses yang Anda kembangkan sebagai gantinya. Saya percaya gagasan ini, bagaimanapun, lebih melekat pada "filsafat Unix" itu sendiri.
Akhirnya, saya kira ini juga yang disinggung oleh James Youngman dengan merekomendasikan
trap
, yang mungkin dapat digunakan dengan cara yang sama. Artinya, jangan abaikan masalahnya ... jebak dan tangani atau Anda bangun suatu hari dan mendapati bahwa tidak ada sub-program yang berhasil sama sekali ;-)sumber
Gunakan
trap
:Atau beralih dari shell ke bahasa lain di mana Anda juga dapat mengatur penangan sinyal.
Perhatikan juga bahwa setelah
bash -c foo..
Anda harus menentukan nilai yang$0
harus diambil (di sini,fnord
) sehingga kata pertama yang dihasilkan olehseq
tidak dimakan.sumber
Letakkan perintah lain di sana untuk 'memakan' sinyal dari program sekarat.
Saya mencoba contoh Anda, secara tidak langsung seperti yang ditunjukkan untuk membuktikan masalahnya ... 'killall sleep' membunuh proses tidur, mengganggu bash, dan xargs berhenti.
Sebagai tes, saya terjebak perintah 'jalankan perintah lain' di antara xargs dan bash ... dalam hal ini '/ usr / bin / time'. kali ini (tanpa kata-kata), killall sleep membunuh proses tidur, tetapi xargs terus berlanjut.
Anda akan menyalurkan output waktu ke / dev / null, dan ini akan melakukan apa yang Anda cari tanpa menulis ulang utama dari proses yang ada.
Saya membayangkan jika saya merenung sejenak saya bisa membuat program lain untuk melakukan hal yang sama tanpa obrolan stderr dari '/ usr / bin / time'. Atau bahkan menulis sendiri, itu hanya turunan 'fork' (atau exec ()).
Ingatlah untuk menggunakan '/ usr / bin / time', karena saya tidak yakin 'waktu' bawaan dari bash akan melakukan 'makan' sinyal yang sama.
sumber
time
untuk tujuan ini adalahenv
, karena yang dilakukannya hanyalah menambahkan nol atau lebih variabel opsional ke lingkungan program yang dijalankannya. Itu tidak memancarkan output sendiri, dan kode kembali dari program yang dipanggil akan diteruskan kembali ke apa pun yang dipanggilenv
.Baik
time
atauenv
bekerja untuk saya (mereka menyampaikan nilai kembali program anak mereka) jadi saya menulisbliss
:kemudian
chmod u+x ~/bliss
dan sesuatu seperti
find_or_similar | xargs ~/bliss fatally_dying_program.sh
sumber