पिछले आदेश समाप्त होने तक बैश स्क्रिप्ट रोकना


20

मेरे पास एक बैश स्क्रिप्ट है जो निम्नलिखित की तरह दिखती है:

##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done

मैं पहले 30 के बाद जारी रखने के लिए लूप के लिए एक और बनाना चाहता हूं। उदाहरण के लिए

##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &

for i in {31..60}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done

मैं नए सेट को शुरू करने से पहले नौकरियों के पहले सेट को समाप्त करना चाहूंगा। लेकिन nohupऐसा लगता है कि वे सभी एक साथ चलते हैं।

मेरे पास nohupइसलिए है क्योंकि मैं अपने सर्वर पर दूरस्थ रूप से लॉगिन करता हूं और वहां नौकरी शुरू करता हूं और फिर अपना बैश बंद कर देता हूं। क्या कोई वैकल्पिक उपाय है?


1
waitबिलिन के लिए मैनुअल खोजें ।
सातु कटुरा

जवाबों:


22

आप आपके waitलिए ऐसा करने के लिए कमांड का उपयोग करना चाहते हैं। आप या तो सभी बच्चों की आईडी प्रक्रिया पर कब्जा कर सकते हैं और विशेष रूप से उनकी प्रतीक्षा कर सकते हैं, या यदि वे केवल पृष्ठभूमि प्रक्रियाएं हैं जो आपकी स्क्रिप्ट बना रही हैं, तो आप बस waitएक तर्क के बिना कॉल कर सकते हैं । उदाहरण के लिए:

#!/bin/bash
# run two processes in the background and wait for them to finish

nohup sleep 3 &
nohup sleep 10 &

echo "This will wait until both are done"
date
wait
date
echo "Done"

6

कुछ बिंदु:

  • यदि आपका लक्ष्य nohupअपने कार्यकर्ता प्रक्रियाओं को मारने से दूरस्थ शेल को बाहर निकलने से रोकना है, तो आपको nohupस्क्रिप्ट पर ही उपयोग करना चाहिए , न कि व्यक्तिगत कार्यकर्ता प्रक्रियाओं पर।

  • जैसा कि यहां बताया गया है , nohupकेवल प्रक्रियाओं को SIGHUP प्राप्त करने और टर्मिनल के साथ बातचीत करने से रोकता है, लेकिन यह शेल और इसकी बाल प्रक्रियाओं के बीच संबंध को नहीं तोड़ता है।

  • उपरोक्त बिंदु के कारण, दो छोरों के बीच nohupएक सरल waitया forदूसरे के कारण, दूसरे forको निष्पादित करने के बाद ही सभी बाल प्रक्रियाएं शुरू हो जाएंगी for

  • एक सरल के साथ wait:

    वर्तमान में सभी सक्रिय बच्चे प्रक्रियाओं के लिए इंतजार कर रहे हैं, और वापसी की स्थिति शून्य है।

  • यदि आपको दूसरी चलाने की आवश्यकता है forयदि पहले में कोई त्रुटि नहीं थी, तो आपको प्रत्येक कार्यकर्ता पीआईडी ​​को बचाने $!और सभी को पास करने की आवश्यकता होगी wait:

    pids=
    for ...
        worker ... &
        pids+=" $!"
    done
    wait $pids || { echo "there were errors" >&2; exit 1; }
    

सर्वर पर अन्य कार्य चल सकते हैं। इसलिए मैं केवल अपने बैच के लिए इंतजार करना चाहता हूं .. वे आर स्क्रिप्ट हैं इसलिए उन्हें अंडर Rया कमांड cc1plusमें चलाया जाता हैtop
masfenix

इसके अलावा, मैं "समांतर" में सभी कमांड चलाने के लिए अंदर nohup का उपयोग करना चाहूंगा। मूल रूप से ये एक वैज्ञानिक कार्यक्रम के लिए सिमुलेशन हैं। मैं कुल मिलाकर 180 सिमुलेशन चलाना चाहता हूं, लेकिन 60 के बैच में। काउंटर को भी 1 से 180 तक जाने की आवश्यकता है। अगर मैं उन्हें एक बार में एक करता हूं, तो बहुत लंबा समय लगेगा।
मैसफेनिक्स

waitbashपृष्ठभूमि की नौकरियों के लिए इंतजार करने का कारण बनता है, यह खुद को पैदा करता है, और कुछ नहीं। यहाँ कुछ भ्रम हो सकता है- इन forछोरों, क्या आपने उन्हें एक फ़ाइल में सहेजा है और उन्हें एक स्क्रिप्ट के रूप में आमंत्रित किया है (जो मैंने माना, ##scriptलाइन के कारण), या आप उन्हें टर्मिनल में हाथ से टाइप कर रहे हैं?
मत्ती डेविड

-1

fgबिलिन का प्रयोग करें । यह पृष्ठभूमि प्रक्रियाओं के खत्म होने तक इंतजार करता है।

help fgविवरण के लिए प्रयास करें।


एक स्क्रिप्ट बिना नौकरी नियंत्रण के चलती है।
Kusalananda

-1

यदि आप अपने दो forछोरों के बीच में निम्न कोड सेगमेंट जैसा कुछ सम्मिलित करते हैं , तो यह मदद कर सकता है।

flag=0

while [ flag -eq 0 ]
do
  ps -ef | grep "Rscript --vanilla" | grep -v grep > /dev/null
  flag=${?}
  sleep 10
done

बेशक, यदि आपके आवेदन Rscriptको सफलतापूर्वक पूरा न करने और चारों ओर से घेरने का मौका है , तो लूप के लिए आपके दूसरे को दौड़ने का मौका नहीं मिल सकता है। कोड खंड ऊपर माना जाता है, पहचानकर्ता के साथ सभी प्रक्रियाएं Rscript --vanillaपूरी हो जाएंगी और ठीक से गायब हो जाएंगी। यह जानने के बिना कि आपका आवेदन क्या करता है और यह कैसे चलता है, मुझे इस धारणा पर भरोसा करना होगा।

संपादित करें

टिप्पणियों के प्रकाश में, यह आपकी आवश्यकताओं के अनुरूप होगा। (इसमें आपके मूल कोड के साथ-साथ पूर्णता के तर्क भी शामिल हैं)

for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
pids[$i]=${!}
done

flag=0

while [ flag -eq 0 ] 
do
  for PID in $(echo ${pids[@]})
  do
    flag=1
    ps -ef | grep ${PID} | grep -v grep >/dev/null; r=${?}
    if [ ${r} -eq 0 ]
    then 
      flag=0
    fi
  done
done

for i in {31..60}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done

में प्रक्रिया नाम topसे पता चलता है तो Rकभी-कभी या cc1plus
मैसफेनिक्स

उस स्थिति में आपको ps -efसूची में दिखाते हुए एक आम भाजक खोजने की आवश्यकता होगी । या प्रत्येक nohupकमांड के बाद , पीआईडी ​​को एक echo ${!}समूह (अधिमानतः एक सरणी) द्वारा रिकॉर्ड करें और पीआईडी के इस समूह के लिए जांचें। जब वे सभी गायब हो जाते हैं, तो आप दूसरे forपाश पर जा सकते हैं
मेलबर्सलान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.