Ctrl + c / नहीं / कैसे करें जबकि लूप को बाधित करें?


11

इस लूप को देखते हुए:

while sleep 10s ; do
  something-that-runs-forever
done

जब मैं Ctrl + C दबाता हूं तो पूरा लूप बाधित हो जाता है। जो मैं करना चाहता हूं वह "कुछ" -प्रक्रिया को बाधित करना है, 10 सेकंड गुजरने दें, और फिर "कुछ" को पुनरारंभ करें।

मैं ctrl + c को केवल "कुछ" को कैसे प्रभावित करूं, और न कि लूप को प्रभावित करूं?

संपादित करें: "बाधा" SIGINT के रूप में। को मार डालो। बीच में बंद करें। बर्खास्त करें। "विराम" के रूप में "रुकावट" नहीं।


यदि आप इसे रोकना चाहते हैं, तो Ctrl + Z का उपयोग क्यों न करें, 10 सेकंड प्रतीक्षा करें और चलाएं fg? Ctrl + C का उपयोग क्यों करें?
terdon

@terdon: टिप्पणी के लिए धन्यवाद, हो सकता है कि मैं जवाब के साथ चला गया। ओपी आवश्यकता पर और अधिक पढ़ने की आवश्यकता है
इनियन

@terdon: मैं इसे रोकना नहीं चाहता। मुझे 10 सेकंड गुजरने चाहिए, जैसे मैंने लिखा था।
bos

आपने कहा What I want to do is to interrupt the "something"-process, let 10 seconds pass, and then restart "something":। यदि आप Ctrl + Z को हिट करते हैं, तो 10s प्रतीक्षा करें और फिर चलाएं fg, ठीक यही होगा। शायद आप अपने प्रश्न को संपादित कर सकते हैं और एक विशिष्ट उदाहरण दे सकते हैं ताकि हम बेहतर समझ सकें?
terdon

3
मुझे लगा कि Ctrl + C के संदर्भ में असंदिग्ध था, लेकिन जाहिर है कि मैं गलत था। मैंने अब संपादन किया है।
bos

जवाबों:


18

यह काम करना चाहिए अगर तुम सिर्फ trap SIGINTकुछ करने के लिए। जैसे :( true)।

#!/bin/sh
trap ":" INT    
while sleep 10s ; do
    something-that-runs-forever
done

something...सिग्नल को अनदेखा करने के बाद से शेल को बाहर निकलने में रुकावट नहीं होती है। हालाँकि, यदि आप ^ सी sleepप्रक्रिया करते हैं, तो यह एक विफलता के साथ बाहर निकल जाएगा, और लूप उसी के कारण बंद हो जाता है। sleepलूप के अंदर की ओर ले जाएं या ऐसा || trueकरने के लिए कुछ जोड़ें ।

ध्यान दें कि यदि आप trap "" INTसिग्नल को पूरी तरह से अनदेखा करने के लिए उपयोग करते हैं (इसके बजाय एक कमांड को असाइन करने के लिए), तो इसे चाइल्ड प्रोसेस में भी अनदेखा कर दिया जाता है, इसलिए तब आप इसे बाधित नहीं कर सकते something...। यह कम से कम बाश के मैनुअल में स्पष्ट रूप से उल्लिखित है :

यदि arg null string है, तो प्रत्येक sigspec द्वारा निर्दिष्ट सिग्नल को शेल द्वारा अनदेखा किया जाता है और इसे इनवोक करता है। [...] शेल में प्रवेश पर नजरअंदाज किए गए सिग्नल फंसे या रीसेट नहीं किए जा सकते।


क्या इसे वर्तमान शेल में भी प्राप्त किया जा सकता है? (एक स्क्रिप्ट में नहीं।)

1
आप do (trap - INT; something-that-runs-forever)कमांड को बाधित करने की अनुमति देना चाह सकते हैं । इसके अलावा, आपको चलाने की आवश्यकता नहीं है :- आप किसी सिग्नल को अनदेखा करने के लिए एक खाली स्ट्रिंग का उपयोग कर सकते हैं trap '' INT:। यह सब POSIX है, और किसी भी आज्ञाकारी शेल (सिर्फ बैश नहीं) पर काम करना चाहिए।
टोबी स्पाइट

यह भी ध्यान रखें कि लेखन SIGINTपूर्ण में सख्ती से पोर्टेबल नहीं है: " कार्यान्वयन के साथ नाम की अनुमति दे सकता SIGउपसर्ग या संकेत के नाम में मामले को अनदेखा विस्तार के रूप में (मेरे जोर)"
टोबी स्पीट

आप खाली स्ट्रिंग को एक संकेत की अनदेखी करने की क्रिया के रूप में पारित कर सकते हैं जैसे trap "" INT(भी पॉज़िक्स)
daf

@TobySpeight, मैंने trap :इसके बजाय जिस कारण का उपयोग किया trap ""था, वह यह था कि संकेत को अनदेखा करने के लिए (लेकिन इसके बजाय इसे नो-ऑप करें), ताकि हमें मुख्य somethingकार्यक्रम को बाधित करने में सक्षम होने के लिए कुछ और करने की आवश्यकता न हो ।
ilkachachu

0

एक अन्य विकल्प something-that-runs-foreverसिग्नल को संभालना है (प्राप्त होने पर इनायत से बाहर निकलना)। बेशक, यह केवल तब करना पड़ता है जब इस कार्यक्रम का उपयोग कई लिपियों में किया जाता है, और स्क्रिप्ट निष्पादन को जारी रखने के लिए CTRL+ पर वांछित व्यवहार Cव्यवस्थित रूप से समान है।


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