यदि किसी भी बच्चे के जन्म की प्रक्रिया विफल हो जाती है, तो सभी को मार डालो और बाहर निकल जाओ


9

मेरी स्क्रिप्ट में मैंने input_aa, input_ab, आदि में एक डेटा सेट को विभाजित किया है, फिर, मैं प्रत्येक को एक ही पायथन स्क्रिप्ट के माध्यम से चलाता हूं, जैसे:

# Execute program on each split file
for part in input_*; do
        python3 $part &
done
wait

मेरा प्रश्न दोतरफा है: मैं कैसे पता लगाऊं कि पायथन प्रक्रिया विफल हो गई है, और जब पता लगाया जाता है, तो मैं सभी बच्चों को कैसे मारूं और एक असफलता के साथ स्क्रिप्ट से बाहर निकलूं?

जवाबों:


10

आप एक प्रक्रिया समूह का उपयोग कर सकते हैं:

set -m
(
   for part in input_*; do
     (python3 "$part" || kill 0) &
   done
   wait
)

set -m(और वैकल्पिक POSIX खोल सुविधा, आवश्यक यूनिक्स शैल सुविधा) अपने स्वयं के प्रक्रिया समूह में नौकरी चलाता है। में bash, yash, zsh, mksh, subshell जहां की नौकरियों है कि set -mसक्षम किया गया है ताकि बाहरी (...)और जो कुछ के भीतर बनाए प्रक्रियाओं है कि एक ही प्रक्रिया समूह में रखा जाएगा।

के लिए dashऔर अन्य ashआधारित गोले, जो केवल शीर्ष स्तर के शेल प्रक्रिया पर काम करते हैं। तो यह कोड तब तक काम करेगा जब तक कि यह सबस्क्रिप्शन में नहीं डाला जाएगा।

एटी एंड टी kshया पुराने SysV / बॉर्न शेल में यह बिल्कुल भी काम नहीं करेगा ।

kill 0 वर्तमान प्रक्रिया समूह के सभी सदस्यों को एक SIGTERM संकेत भेजता है।


मारपीट में। मैंने एक शेबंग क्यों शामिल किया - आवश्यक शेल स्पष्ट नहीं है। अच्छा उत्तर
जिम् म्कारामारा

@jimmcnamara, कि में काम करता है bash, dash, yash, mksh, zsh। मूल रूप से कोई भी POSIX शेल लेकिन AT & T ksh। set -m(अंडर-) POSIX में निर्दिष्ट है, लेकिन एक वैकल्पिक सुविधा के रूप में।
स्टीफन चेज़लस

मैं सोलारिस का उपयोग करता हूं। / बिन / श नहीं उड़ेंगे।
जिम म्कारामारा

@jimmcnamara, Solaris 10 पर नो / बिन / श और बॉर्न शेल (POSIX शेल नहीं) और 11, AT & T ksh पर। जैसा कि मैंने कहा, यह बाश, डैश, यश, मक्ष, zsh में काम करता है।
स्टीफन चेज़लस

1
@mikeserv, जो इस प्रक्रिया को 1 में बदल देगा, लेकिन इसे प्रक्रिया समूह से बाहर नहीं ले जाएगा। kill 0प्रक्रिया समूह के सभी सदस्यों को मारता है जो भी उनके माता-पिता हैं। ps -jप्रक्रिया समूह आईडी देखने के लिए देखें।
स्टीफन चेज़लस

3

यह एक उदाहरण है। इस के साथ पहले खेलते हैं कि आपको क्या चाहिए। यह बहुत टूट नहीं सकता है।

#!/bin/bash
# Example of killing off all children

> killfile
> outfile.err
kill_em()
{
   echo 'killing all children ' > 2
   while read pid
   do
      kill -0 $pid && kill -9 $pid  # if still running kill it
   done < killfile
   exit 1
}

export grandparentpid=$$
trap 'kill_em' 6
for i in 2 2 3 4 5 6 7 8 9 10
do
        ( sleep $i && ls oinkle  >> outfile 2>> outfile.err &
          pid=$!
          echo $pid >> killfile
          wait $!
          [ $? -ne 0 ] && kill -6 $grandparentpid
        ) &
done
wait

यह जानबूझकर विफल होने के लिए सेटअप है क्योंकि ls oinkleविफल हो जाएगा (मेरी मशीन पर)।

जब आपको स्टार्टर स्क्रिप्ट के साथ छेड़छाड़ करने के बाद आपको क्या चाहिए --- बदलें:

for i in 2 2 3 4 5 6 7 8 9 10

सेवा:

for part in input_* 

परिवर्तन:

sleep $i && ls oinkle 

सेवा:

python3 $part 

लॉग सहेजने के लिए पुनर्निर्देशन हैं। आप उन्हें नहीं चाहते हो सकता है।


यह थोड़ा रिस्की है। यदि नौकरियों में से एक विफल हो जाती है इससे पहले कि अन्य सभी शुरू हो गए हैं, तो आपके killfileपास उन नौकरियों के सभी ग्रिड नहीं हो सकते हैं जो शुरू हो चुके हैं।
स्टीफन चेजलस

कुछ ख़राब प्रथाएँ: जैसे निर्विवाद चर, नामों के बजाय संकेत संख्याओं का उपयोग, संकेत 6 का उपयोग करें (उदाहरण के लिए Linux amd64 पर ABRT), उपयोगकर्ता संकेत के रूप में USR1 / USR2 के बजाय [ $? -ne 0 ]...
स्टीफन चेसनास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.