बैश लूप - जब मैं एक कमांड के अंदर कंट्रोल-सी दबाता हूं तो लूप को कैसे रोकें?


35

मैं कुछ निर्देशिकाओं को rsyncing कर रहा हूं। मेरे पास एक बैश टर्मिनल खुला है और मैं इस तरह से कुछ कर रहा हूं:

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done

हालांकि अगर मैं पूरी चीजों को रोकना चाहता हूं, तो मैं कंट्रोल-सी दबाता हूं। यह rsync को रोकता है, लेकिन फिर यह अगले एक पर जा रहा है। इस मामले में मुझे एहसास हुआ कि क्या हुआ है और फिर कंट्रोल-सी को एक पागल की तरह दबाएं जब तक कि चीजें फिर से काम न करें।

क्या इसे 'ठीक' करने का कोई तरीका है। मैं ऐसा चाहता हूं, अगर मेरे पास ऐसा कोई लूप है, और कंट्रोल-सी दबाएं, कि यह मुझे मेरे बैश शेल में वापस कर देगा।


6
डेनिस का उत्तर सही है, लेकिन अगर आपने ऐसा नहीं किया है, तो आपको इसे 'पागल की तरह दबाने' की ज़रूरत नहीं है, बस इसे पकड़ कर रखें और कीबोर्ड को इसे फिर से दोहराने दें :-)
काइल ब्रांट

मैं हमेशा Cntl-C को दबाए रखता हूं, आम तौर पर ठीक काम करता है।
स्कॉट एलन मिलर

जवाबों:


33
for DIR in * ; do rsync -a $DIR example.com:somewhere/ || break; done

अगर किसी कारणवश कोई rsync रन विफल हो जाता है तो यह भी लूप से बाहर निकल जाएगा।


4
अतिरिक्त टिप: यदि आप एक नेस्टेड लूप में हैं, और पूरी तरह से समाप्त करना चाहते हैं, तो break 2"2" का उपयोग करें (नेस्टेड लूप की संख्या के साथ जिसे आप समाप्त करना चाहते हैं)।
डोलन एंटेनुची

26

डेनिस के उत्तर पर विस्तार करने के लिए, आपका कोड जैसा दिख सकता है:

trap "echo Exited!; exit;" SIGINT SIGTERM

एक कामकाजी उदाहरण के लिए (जिसमें rsync शामिल होता है), http://gist.github.com/279849 देखें


धन्यवाद, यह एक सामान्य समाधान है जिसने मेरे लिए काम किया
wi1

25

आप नियंत्रण-सी के लिए एक जाल सेट कर सकते हैं।

trap <command> SIGINT

commandनियंत्रण-सी दबाए जाने पर निष्पादित करेगा । बस trapअपनी स्क्रिप्ट में उस बिंदु पर कहीं एक बिंदु पर रखें जहां आप चाहते हैं कि यह प्रभावी हो जाए।


6

जब आप कोष्ठक के अंदर आदेशों की एक स्ट्रिंग डालते हैं, तो स्ट्रिंग एक एकल प्रक्रिया के रूप में कार्य करेगी, और जब आप हिट करते हैं, तो उसे संकेत प्राप्त होगा और समाप्त कर देगा Ctrl- C:

(for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done)

परंतु! rsyncकमांड के मामले में , यह कई स्रोतों की अनुमति देता है, इसलिए आपके द्वारा लिखा गया कोड इस तरह बेहतर लिखा जाएगा:

rsync -a * example.com:somewhere/

6
  1. Ctrl-Zस्क्रिप्ट को निलंबित करने के लिए दबाएं ;
  2. kill %%

इस उत्तर में क्रेडिट, स्पष्टीकरण और अधिक विवरण ।


यह बहुत अच्छा है क्योंकि यह "पोस्ट फैक्टो" काम करता है जब आप पहले से शुरू किए गए लंबे समय तक चलने वाले लूप को बाधित करना चाहते हैं।
निक मैट्टो

0

मैं अपने लूप में एक और कमांड डालता हूं जिसे आसानी से बाधित किया जा सकता है। इसे दो ctrl-C दबाए जाने की आवश्यकता है।

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; sleep 1 ; done

यह इस rsync के लिए इतना बढ़िया समाधान नहीं है, जिसे आप शायद जल्दी से चलाना चाहते हैं। लेकिन यह इस तरह से अन्य छोरों के लिए अच्छी तरह से काम करता है:

while true ; do ping -c 10 example.com ; sleep 1 ; done

यह लूप लूप के माध्यम से हर बार example.com के पते को फिर से खोजेगा, जो कि यदि आप DNS परिवर्तन के लिए देख रहे हैं तो उपयोगी है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.