Ctrl-C टर्मिनल को स्वयं क्यों नहीं मारता है?


39

जब हम इसे खोलते हैं तो टर्मिनल चल रहा होता है।

luvpreet@DHARI-Inspiron-3542:/$

मैंने अभी इसे खोला है। इसलिए, जब मैं Ctrl+ दबाता हूं, तो Cयह खुद को क्यों नहीं मारता है और टर्मिनल को बंद कर देता है ??


21
टर्मिनल टर्मिनल में नहीं चल रहा है ;-)
Pilot6

3
नियंत्रण-डी कार्यों के बारे में क्यों: unix.stackexchange.com/a/110248/14305
जानूस ट्रॉल्सन

जवाबों:


48

Ctrl+ Cव्यवधान संकेत है। जब आप इसे टर्मिनल में लिखते हैं, तो बैश अग्रभूमि में नौकरी के लिए SIGINT भेजता है। यदि कोई नौकरी नहीं है (जो आपके द्वारा बस टर्मिनल खोलने पर मामला है), तो कुछ भी नहीं होता है। टर्मिनल एमुलेटर प्रोग्राम शेल में चलने वाला काम नहीं है, इसलिए, इसे सिग्नल नहीं मिलता है और यह बंद नहीं होता है।

यदि आप नियंत्रण कुंजी के साथ टर्मिनल को बंद करना चाहते हैं, तो Ctrl+ D(EOF) का उपयोग करें, जो बैश को बाहर निकलने का कारण बनता है (और टर्मिनल को भी बंद कर देता है)।

इसे भी देखें: संकेतों पर और अधिक गहराई में बैश बिगिनर की गाइड कैसे सिग्नल काम करता है
ध्यान दें: यह उत्तर टिप्पणियों के पोस्ट किए जाने के बाद से संपादित किया गया है


4
उचित शब्द यह है कि शेल सिग्नल को "ट्रैप" करेगा। जब आप दूसरी विंडो के भीतर से टर्मिनल विंडो लॉन्च करते हैं तो अलग कहानी होती है। मूल विंडो में ctrl + c भेजने से बच्चे की प्रक्रिया में बाधा होगी।
सर्गी कोलोडियाज़नी

1
इसके अलावा, GUI विंडो को X11 सर्वर से आने वाले विशिष्ट संकेतों को फंसाने का भी निर्देश दिया जा सकता है। इसी तरह से आपके पास बिना सहेजे हुए काम के लिए पॉपअप हो सकते हैं, या ब्राउज़र में टैब खोल सकते हैं
Sergiy Kolodyazhnyy

8
@chrylis टर्मिनल प्रोग्राम सिर्फ ctrl-c कैरेक्टर भेजता है, यह वास्तव में कर्नेल ट्टी लेयर है जो इसे सिग्नल में बदल देता है।
रैंडम 832

3
@chrylis: और टर्मिनल, या इसके अंदर चल रहा एक कार्यक्रम - उदाहरण के लिए एक पाठ संपादक - कुछ अन्य कार्रवाई के लिए अच्छी तरह से Ctl-C का अनुवाद कर सकता है।

3
मुझे नहीं लगता कि bashजब ctrl-c दबाया जाता है तो किसी भी कार्यक्रम को समाप्त कर देगा। यह सिर्फ कर्नेल को बताएगा कि कौन सा प्रोसेस समूह सक्रिय है और टर्मिनल प्रोग्राम से ctrl-c प्राप्त होने पर कर्नेल उस प्रोसेस ग्रुप को सिग्नल उत्पन्न करेगा।
कास्परड

32

^Cकीस्ट्रोक, अन्य कीस्ट्रोक्स तरह *, जादू नहीं है - यह किसी कीकोड जो भी करने के लिए कार्यक्रम ध्यान केंद्रित किया भेजता है। (एक्स में, कीकोड 54 के लिए C0x4 के एक संशोधक के साथ है Ctrl।) जिस प्रोग्राम को कुंजी की स्ट्रीम प्राप्त हो रही है, वह उनके साथ कुछ उपयुक्त करने के लिए जिम्मेदार है - याद रखें कि कई GUI अनुप्रयोगों में, क्लिपबोर्ड पर कीस्ट्रोक कॉपी करता है।

जब जीयूआई टर्मिनल एमुलेटर (जैसे, कोनसोल) या वर्चुअल टर्मिनल एक कीस्ट्रोक प्राप्त करता है जो कि इसकी व्याख्या करता है ^C, तो यह तीन चीजों में से एक कर सकता है। यदि टर्मिनल कच्चे मोड में है , तो चल रहे कार्यक्रम ने टर्मिनल को स्वयं विशेष कुंजी की कोई भी हैंडलिंग नहीं करने और उन्हें सीधे कार्यक्रम में पास करने के लिए कहा है। कुछ प्रोग्राम जो लाइन एडिटिंग जैसी उन्नत सुविधाओं का समर्थन करते हैं, वे पूर्ण कच्चे कीस्ट्रोक्स और पाठ की संसाधित लाइनों के बीच कुछ कॉन्फ़िगरेशन में कीबोर्ड इनपुट प्राप्त करते हैं; bash, उदाहरण के लिए, एक समय में एक कीस्ट्रोक्स प्राप्त करता है। ^Cटर्मिनल द्वारा व्याख्या की जाती है, लेकिन बैकस्पेस कुंजी को शेल के रूप में भेजा जाता है।

हालांकि, अधिकांश कार्यक्रम, पका हुआ मोड का उपयोग करते हैं (क्योंकि यह कच्चा नहीं है), जहां टर्मिनल वास्तव में उन्हें कार्यक्रम में भेजने से पहले कुछ बुनियादी कीस्ट्रोक्स की व्याख्या करता है (यही कारण है कि आप बैकस्पेस का उपयोग कर सकते हैं cat)। इस मोड में, टर्मिनल खुद ^Cकीस्ट्रोके को एक SIGINTसंकेत में अनुवाद करता है और इसे बाल प्रक्रिया में भेजता है। चूंकि टर्मिनल ने सिग्नल उत्पन्न किया, इसलिए यह भ्रमित नहीं होगा और समाप्त नहीं होगा।

  • SysRq वास्तव में जादू है।

जाहिर है यहां सुपर-प्रासंगिक नहीं है, लेकिन सामान्य कंप्यूटिंग के लिए वहां से अधिक जादू कीस्ट्रोक्स हैं। सबसे प्रसिद्ध, विंडोज दुनिया में Ctrl+ Alt+ Delete, जहां कुंजी संयोजन जादू के बहुत करीब है (इसका उपयोग विंडोज को काम करने के लिए किया जा सकता है, यह बहुत ही जादुई है! और अपने आप में!), क्योंकि यह हार्ड-कोडेड है सिस्टम में बाधित करने के लिए! और बहुत ज्यादा सब कुछ ओवरराइड करता है — SysRqउस अर्थ में बहुत समान ।
केरान

7
बैश कच्चे मोड का उपयोग नहीं करता है - यह चरित्र-पर-एक-समय मोड अर्थात cbreak/ का उपयोग करता है -icanon, लेकिन यह isigमोड सेट को छोड़ देता है, और जब आप उन्हें दबाए जाते हैं, तो कुंजी दबाते समय वास्तविक संकेत प्राप्त होते हैं। यह आपके SIGINTद्वारा वर्णित व्यवहार के अनुसार काम करता है (यह सिर्फ पंक्ति संपादन को रद्द नहीं करता है, यह किसी भी आंतरिक कमांड को भी रद्द करता है जो लूप में चल सकता है), और पूरी तरह से अनदेखा करता है SIGTSTPऔर SIGQUIT। अन्य प्रोग्राम, जैसे vi, नहीं हो सकता है।
रैंडम 32३२

1
@KRyan Ctrl+ Alt+ Deleteआज की तुलना में और भी अधिक जादुई हुआ करते थे - blogs.msdn.microsoft.com/oldnewthing/20140912-00/?p=44083 । हालांकि मैं दिल से एक लिनक्स व्यक्ति हूं, मैं अक्सर उस हद तक जागता हूं जब शुरुआती दिनों में विंडोज इस तरह के सीमित संसाधनों के साथ चीजों को उपयोगकर्ता के अनुकूल और तार्किक बनाता था।
मुज़ेर

कुछ OS पर, भले ही किसी अन्य प्रोग्राम ने सिस्टम को फोकस किया हो (विंडो मैनेजर मुझे लगता है?) वास्तव में टर्मिनल एमुलेटर के होने से पहले कीपेस हो जाता है। अगर आप कीबोर्ड शॉर्टकट्स को स्नैप विंडो, ओपन एप्लिकेशन, स्क्रिप्ट को ट्रिगर करने में सक्षम हैं तो कुंजी दबाए जाने से पहले टर्मिनल एमुलेटर पर भेजे जाते हैं जो आपके द्वारा कॉन्फ़िगर किए गए किसी भी शॉर्टकट के लिए जांचे जाते हैं। और एक और उदाहरण यदि आपके पास कोई एप्लिकेशन ^cनहीं है तो विंडो मैनेजर को नहीं मारेगा :)। कच्चे / पके हुए चरित्र पर एक समय की सामग्री पर टिप्पणी करने में सक्षम नहीं है, लेकिन इसका जवाब इस बात पर है कि कीस्ट्रोक कैसे उत्पन्न होता हैSIGINT
अजय

2
" पका हुआ मोड (क्योंकि यह कच्चा नहीं है)": मैं ... अवाक हूं। इतने सालों के बाद, मैंने कभी संबंध नहीं बनाया।
isanae

8

^Cआमतौर पर संकेत (देखें ) के stty -aलिए मैप किया जाता है SIGINT(देखें man 7 signal)।

एक अन-पकड़ा SIGINTचल रही प्रक्रिया को बाधित करता है, लेकिन ...

SIGINT संकेतों में से एक है जो एक प्रक्रिया के लिए व्यवहार को निर्दिष्ट कर सकता है ("एक सिग्नल को पकड़ने")।

जिसे आप "टर्मिनल" कैच कहते हैं SIGINT, और काम पर वापस चला जाता है।


7

जब मैं एक शुरुआत कर रहा था तो मुझे वह हिस्सा याद आ रहा था कि जब मैं कमांड लाइन का उपयोग कर रहा था तब मैं वास्तव में दो अलग कार्यक्रमों, एक टर्मिनल और एक शेल (जैसे bash) का उपयोग कर रहा था

शेल वह है जो आप पहले से ही जानते हैं, एक प्रोग्राम जो इनपुट कमांड या स्क्रिप्ट के रूप में लेता है, उन्हें निष्पादित करता है और उनके आउटपुट प्रिंट करता है।

दूसरी तरफ टर्मिनल उपयोगकर्ता और कार्यक्रम के बीच बीच में एक आदमी की तरह होता है (जो प्रोग्राम आमतौर पर बैश या मछली की तरह एक खोल होता है)। टर्मिनल क्या करता है कीबोर्ड से उदाहरण के लिए इनपुट को पढ़ने के लिए, हो सकता है कि उस इनपुट को किसी तरह से संसाधित करें, और इसे अन्य प्रोग्राम (बैश) पर रीडायरेक्ट करें।

इसके अलावा यह दूसरे तरीके से भी काम करता है, जब अन्य प्रोग्राम कुछ आउटपुट करता है, कि कुछ को टर्मिनल पर रीडायरेक्ट किया जाता है, तो यह टर्मिनल का काम है कि वह स्क्रीन पर कुछ आउटपुट करे। इनपुट प्राप्त करने और इसे स्क्रीन पर प्रिंट करने के बीच टर्मिनल विभिन्न तरीकों से प्राप्त इनपुट की व्याख्या कर सकता है।

उदाहरण के लिए यदि कोई प्रोग्राम निम्न अनुक्रम को आउटपुट करता है:

\e[0;31m some extra foobar text

टर्मिनल लाल रंग के अक्षरों के साथ स्क्रीन पर "कुछ अतिरिक्त फोब्बर टेक्स्ट" का उत्पादन करेगा। ऐसा इसलिए है क्योंकि टर्मिनल उस अजीब कोड का इलाज एक विशेष तरीके से करता है जो कोड को लाल रंग में निम्न आउटपुट को प्रिंट करने के लिए संकेत करता है।

इसी तरह जब उपयोगकर्ता दबाता है Ctrl - C, तो इसके बारे में एकमात्र विशेष बात यह है कि टर्मिनल इसे एक विशेष तरीके से इलाज करने का विकल्प चुनता है, इस कुंजी अनुक्रम के बारे में कोई अन्य विशेष बात नहीं है। विशेष रूप से यह संकेत देता है कि इंटरप्ट सिग्नल (SIGINT) को उस प्रक्रिया में भेजा जाए जो टर्मिनल के अंदर चल रही है, वह शेल है। यदि उस क्षण में कोई भी प्रोग्राम मौजूद है जिसे शेल द्वारा देखा गया है और वर्तमान में अग्रभूमि में चल रहा है तो यह भी संकेत प्राप्त करता है। अब शेल में इस सिग्नल के लिए एक विशेष हैंडलर है और कुछ भी नहीं होता है। लेकिन ज्यादातर कार्यक्रमों में डिफ़ॉल्ट हैंडलर होते हैं जो SIGINT के मामले में सिर्फ बाहर निकलते हैं।


5

हर सिग्नल में इससे जुड़ी एक डिफ़ॉल्ट कार्रवाई होती है। सिग्नल के लिए डिफ़ॉल्ट क्रिया वह क्रिया है जो स्क्रिप्ट या प्रोग्राम तब करता है जब वह सिग्नल प्राप्त करता है।

Ctrl+ C"इंटरप्ट" सिग्नल ( SIGINT ) भेजता है , जो अग्रभूमि में चल रही नौकरी की प्रक्रिया को समाप्त करने में चूकता है।

Ctrl+ Dटर्मिनल को बताता है कि उसे मानक इनपुट पर ईओएफ दर्ज करना चाहिए , जो बाहर निकलने की इच्छा के रूप में व्याख्या करता है ।

एक प्रक्रिया INT सिग्नल को नजरअंदाज करने का विकल्प चुन सकती है, और जब यह इंटरएक्टिव मोड में चल रहा हो तो बैश करता है।

से मैनुअल :

जब बैश संवादात्मक होता है, तो किसी भी जाल की अनुपस्थिति में, यह SIGTERM को अनदेखा करता है (ताकि किल 0 एक संवादात्मक शेल को नहीं मारता), और SIGINT को पकड़ा और संभाला जाता है (ताकि प्रतीक्षा का अवरोध बाधित हो)। सभी मामलों में, मारना SIGQUIT को नजरअंदाज करता है। अगर नौकरी पर नियंत्रण होता है, तो SIGTTIN, SIGTTOU और SIGTSTP को नजरअंदाज करें।


इसे जाल के साथ समझें :

ट्रैप एक फ़ंक्शन है जिसे शेल में बनाया गया है जो हार्डवेयर सिग्नल और अन्य घटनाओं पर प्रतिक्रिया करता है। यह संचालकों को तब परिभाषित और सक्रिय करता है जब शेल सिग्नल या अन्य विशेष स्थितियों को प्राप्त करता है।

trap [-lp] [arg] [sigspec …]

-l संकेत नामों और उनके संबंधित नंबरों की एक सूची प्रिंट करें।
-pप्रत्येक SIGNAL_SPEC से जुड़े ट्रैप कमांड को प्रदर्शित करें।

arg को पढ़ा और निष्पादित किया जाना चाहिए जब शेल सिग्नल सिगस्पेक प्राप्त करता है। प्रत्येक सिगस्पेक एक संकेत नाम या एक संकेत संख्या है। संकेत नाम केस असंवेदनशील हैं और SIG उपसर्ग वैकल्पिक है।

एक तो sigspec है 0 या निकलें , आर्ग निष्पादित किया जाता है जब खोल बाहर निकलता है। इसे समझने के लिए, टर्मिनल को बंद करें और .bashrcफ़ाइल में निम्नलिखित पंक्ति को संपादित करने के बाद इसे खोलें ।

trap 'notify-send "Ctrl D pressed"' 0

Ctrl D exitटर्मिनल से बाहर निकलने के लिए कमांड के समान है ।

यदि आप चाहते हैं कि Bash INT सिग्नल प्राप्त करने से बाहर निकल जाए, तो इंटरेक्टिव मोड में भी, आप निम्नलिखित को अपने साथ जोड़ सकते हैं ~/.bashrc:

trap 'exit' INT

या

trap 'exit' 2

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