Ctrl + C के साथ बैश स्क्रिप्ट को रोकने में असमर्थ


42

मैंने एक साधारण बैश स्क्रिप्ट लिखी जिसमें लूप के साथ एक तारीख और पिंग को रिमोट मशीन से प्रिंट किया गया:

#!/bin/bash
while true; do
    #     *** DATE: Thu Sep 17 10:17:50 CEST 2015  ***
    echo -e "\n*** DATE:" `date` " ***";
    echo "********************************************"
    ping -c5 $1;
done

जब मैं इसे एक टर्मिनल से चलाता हूं तो मैं इसे रोक नहीं पा रहा हूं Ctrl+C। ऐसा लगता है कि यह ^Cटर्मिनल को भेजता है , लेकिन स्क्रिप्ट बंद नहीं होती है।

MacAir:~ tomas$ ping-tester.bash www.google.com

*** DATE: Thu Sep 17 23:58:42 CEST 2015  ***
********************************************
PING www.google.com (216.58.211.228): 56 data bytes
64 bytes from 216.58.211.228: icmp_seq=0 ttl=55 time=39.195 ms
64 bytes from 216.58.211.228: icmp_seq=1 ttl=55 time=37.759 ms
^C                                                          <= That is Ctrl+C press
--- www.google.com ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 40.887/59.699/78.510/18.812 ms

*** DATE: Thu Sep 17 23:58:48 CEST 2015  ***
********************************************
PING www.google.com (216.58.211.196): 56 data bytes
64 bytes from 216.58.211.196: icmp_seq=0 ttl=55 time=37.460 ms
64 bytes from 216.58.211.196: icmp_seq=1 ttl=55 time=37.371 ms

चाहे मैं इसे कितनी भी बार दबाऊं या कितनी जल्दी करूं। मैं इसे रोक नहीं पा रहा हूं।
परीक्षण करें और अपने आप से महसूस करें।

एक साइड सॉल्यूशन के रूप में, मैं इसे रोक रहा हूं Ctrl+Z, जो इसे रोकता है और फिर kill %1

यहाँ वास्तव में क्या हो रहा है ^C?

जवाबों:


26

क्या होता है कि दोनों है bashऔर pingSIGINT प्राप्त ( bashकिया जा रहा नहीं इंटरैक्टिव, दोनों pingऔर bashएक ही प्रक्रिया समूह है जो इंटरैक्टिव खोल आप से है कि स्क्रिप्ट चलाने के द्वारा बनाई गई है और सेट टर्मिनल के अग्रभूमि प्रक्रिया समूह के रूप में में चलाने)।

हालाँकि, bashउस SIGINT को असिंक्रोनस तरीके से हैंडल करता है, केवल वर्तमान में चल रहे कमांड से बाहर निकलने के बाद। bashकेवल उस SIGINT को प्राप्त करने पर बाहर निकलता है यदि वर्तमान में चल रही कमांड SIGINT की मृत्यु हो जाती है (अर्थात इसकी निकास स्थिति इंगित करती है कि यह SIGINT द्वारा मार दी गई है)।

$ bash -c 'sh -c "trap exit\ 0 INT; sleep 10; :"; echo here'
^Chere

इन सबसे ऊपर, bash, shऔर sleepSIGINT जब मैं Ctrl-C दबाएँ प्राप्त करते हैं, लेकिन shबाहर निकलता है एक 0 बाहर निकलने के कोड के साथ सामान्य रूप से है, इसलिए bashSIGINT पर ध्यान नहीं देता है, जो कारण है कि हम "यहाँ" देखें।

pingकम से कम iputils से एक, ऐसा व्यवहार करता है। बाधित होने पर, यह आँकड़े प्रिंट करता है और 0 या 1 के बाहर निकलने की स्थिति के साथ बाहर निकलता है, इस पर निर्भर करता है कि उसके पिंग्स का उत्तर दिया गया था या नहीं। इसलिए, जब आप pingरनिंग के दौरान Ctrl-C दबाते हैं, तो bashजो नोट्स आपने Ctrl-Cअपने SIGINT हैंडलर्स में दबाए हैं , लेकिन चूंकि pingसामान्य रूप से बाहर निकलता है, bashइसलिए बाहर नहीं निकलता है।

यदि आप sleep 1उस लूप में जोड़ते हैं और दौड़ते Ctrl-Cसमय दबाते हैं sleep, क्योंकि sleepSIGINT पर कोई विशेष हैंडलर नहीं है, तो वह मर जाएगा और bashयह रिपोर्ट करेगा कि यह एक SIGINT की मृत्यु हो गई है, और उस मामले bashमें बाहर निकल जाएगा (यह वास्तव में SIGINT के साथ खुद को मार देगा। अपने अभिभावक को रुकावट की सूचना देना)।

जैसा कि क्यों bashव्यवहार करता है, मुझे यकीन नहीं है और मैं ध्यान देता हूं कि व्यवहार हमेशा निर्धारक नहीं होता है। मैंने सिर्फ विकास मेलिंग सूची पर सवालbash पूछा है ( अपडेट : @ जाइल्स ने अब अपने उत्तर में कारण को नीचे कर दिया है )।

केवल दूसरे शेल में मैंने पाया कि इसी तरह का व्यवहार ksh93 है (अपडेट, जैसा कि @Jilles द्वारा उल्लेख किया गया है, इसलिए FreeBSD करता हैsh )। वहाँ, SIGINT को स्पष्ट रूप से नजरअंदाज किया गया लगता है। और ksh93जब भी कोई आदेश SIGINT द्वारा मार दिया जाता है तब बाहर निकलता है।

आपको bashऊपर जैसा ही व्यवहार मिलता है, बल्कि:

ksh -c 'sh -c "kill -INT \$\$"; echo test'

आउटपुट "परीक्षण" नहीं करता है। यही है, यह बाहर निकलता है (वहाँ खुद को SIGINT के साथ मारकर) अगर यह SIGINT के मरने का इंतजार कर रहा था, तो भी, खुद को उस SIGINT को प्राप्त नहीं हुआ था।

चारों ओर एक काम एक जोड़ने के लिए किया जाएगा:

trap 'exit 130' INT

bashSIGINT प्राप्त करने के लिए बाहर निकलने के लिए बाध्य करने के लिए स्क्रिप्ट के शीर्ष पर (ध्यान दें कि किसी भी स्थिति में, SIGINT को समकालिक रूप से संसाधित नहीं किया जाएगा, केवल वर्तमान में चल रहे कमांड से बाहर निकलने के बाद)।

आदर्श रूप से, हम अपने माता-पिता को रिपोर्ट करना चाहते हैं कि हम एक SIGINT से मर गए (ताकि यदि bashउदाहरण के लिए यह एक और स्क्रिप्ट है, तो वह bashस्क्रिप्ट भी बाधित होती है)। ऐसा करना exit 130SIGINT के मरने के समान नहीं है (हालांकि कुछ गोले $?दोनों मामलों के लिए समान मूल्य पर सेट होंगे ), हालांकि इसका उपयोग अक्सर SIGINT द्वारा मौत की रिपोर्ट करने के लिए किया जाता है (उन प्रणालियों पर जहां SIGINT 2 सबसे अधिक है)।

हालाँकि bash, ksh93या FreeBSD के लिए sh, यह काम नहीं करता है। उस 130 बाहर निकलने की स्थिति को SIGINT द्वारा मृत्यु के रूप में नहीं माना जाता है और एक मूल स्क्रिप्ट वहां गर्भपात नहीं करेगी ।

तो, SIGINT प्राप्त करने पर SIGINT के साथ हमारे आप को मारने के लिए संभवतः एक बेहतर विकल्प होगा:

trap '
  trap - INT # restore default INT handler
  kill -s INT "$$"
' INT

1
jilles का जवाब "क्यों" बताता है। एक उदाहरण के रूप में , विचार करें  for f in *.txt; do vi "$f"; cp "$f" newdir; done। यदि उपयोगकर्ता किसी एक फाइल को संपादित करते समय Ctrl + C टाइप viकरता है , तो बस एक संदेश प्रदर्शित करता है। यह उचित लगता है कि उपयोगकर्ता द्वारा फाइल को संपादित करने के बाद लूप जारी रहना चाहिए। (और हां, मुझे पता है कि आप कह सकते हैं vi *.txt; cp *.txt newdir; मैं सिर्फ forएक उदाहरण के रूप में लूप प्रस्तुत कर रहा हूं ।)
स्कॉट

@ सच, ​​अच्छी बात है। हालांकि vi(अच्छी तरह vimसे कम से कम) isigसंपादन करते समय tty को अक्षम कर देता है ( :!cmdहालांकि जब आप इसे चलाते हैं तो यह स्पष्ट रूप से नहीं होता है , और यह उस मामले में बहुत अधिक लागू होगा)।
स्टीफन चेजलस

@ देखें, अपने संपादन में सुधार के लिए मेरा संपादन देखें।
स्टीफन चेज़लस

@ स्टीफनचैलेजस धन्यवाद। ऐसा इसलिए है क्योंकि pingSIGINT प्राप्त करने के बाद 0 के साथ बाहर निकलता है। मुझे एक समान व्यवहार मिला जब एक बैश स्क्रिप्ट में sudoइसके बजाय होता है ping, लेकिन sudoSIGINT प्राप्त करने के बाद 1 के साथ बाहर निकलता है। unix.stackexchange.com/questions/479023/…
टिम

13

स्पष्टीकरण यह है कि बैश डब्ल्यूसीई (प्रतीक्षा और सहकारी निकास) के लिए प्रति और http://www.cons.org/cracauer/sigint.html प्रति SIGQUIT को लागू करता है । इसका मतलब है कि यदि बैश किसी प्रक्रिया से बाहर निकलने के लिए इंतजार करते समय SIGINT या SIGQUIT को प्राप्त करता है, तो यह तब तक इंतजार करेगा जब तक कि यह प्रक्रिया समाप्त नहीं हो जाती है और यदि प्रक्रिया उस संकेत पर बाहर निकल जाती है तो वह खुद बाहर निकल जाएगी। यह सुनिश्चित करता है कि जो प्रोग्राम अपने यूजर इंटरफेस में SIGINT या SIGQUIT का उपयोग करते हैं, वे अपेक्षित रूप से काम करेंगे (यदि सिग्नल ने प्रोग्राम को समाप्त करने का कारण नहीं बनाया, तो स्क्रिप्ट सामान्य रूप से जारी रहेगी)।

एक नकारात्मक पक्ष ऐसे कार्यक्रमों के साथ दिखाई देता है जो SIGINT या SIGQUIT को पकड़ते हैं, लेकिन फिर इसकी वजह से समाप्त हो जाते हैं, लेकिन स्वयं से सिग्नल को हटाकर सामान्य निकास () के बजाय इसका उपयोग करते हैं। ऐसे प्रोग्राम को कॉल करने वाली स्क्रिप्ट को बाधित करना संभव नहीं हो सकता है। मुझे लगता है कि वास्तविक फिक्सिंग ऐसे कार्यक्रमों में है जैसे पिंग और पिंग 6।

इसी तरह के व्यवहार को ksh93 और फ्रीबीएसडी के / बिन / श द्वारा लागू किया जाता है, लेकिन अधिकांश अन्य गोले द्वारा नहीं।


धन्यवाद, यह बहुत मायने रखता है। मैं ध्यान देता हूं कि फ्रीबीएसडी श या तो गर्भपात नहीं करता है जब सीएमडी निकास (130) के साथ बाहर निकलता है, जो कि बच्चे की सिगइंट द्वारा मौत की रिपोर्ट करने का एक सामान्य तरीका है ( exit(130)यदि आप रुकावट करते हैं तो mksh उदाहरण के लिए करता है mksh -c 'sleep 10;:')।
स्टीफन चेजलस

5

जैसा कि आप अनुमान लगाते हैं, यह SIGINT के अधीनस्थ प्रक्रिया में भेजे जाने के कारण है, और उस प्रक्रिया के बाद शेल जारी रहता है।

इसे बेहतर तरीके से संभालने के लिए, आप जो कमांड चला रहे हैं, उससे बाहर निकलने की स्थिति की जांच कर सकते हैं। यूनिक्स रिटर्न कोड दोनों विधि को इनकोड करता है जिसके द्वारा एक प्रक्रिया बाहर निकलती है (सिस्टम कॉल या सिग्नल) और किस मूल्य को पारित किया गया exit()या किस संकेत ने प्रक्रिया को समाप्त कर दिया। यह सब बल्कि जटिल है, लेकिन इसका उपयोग करने का सबसे तेज़ तरीका यह जानना है कि सिग्नल द्वारा समाप्त की गई प्रक्रिया में एक गैर-शून्य रिटर्न कोड होगा। इस प्रकार, यदि आप अपनी स्क्रिप्ट में रिटर्न कोड की जांच करते हैं, तो आप अनावश्यक प्रक्रिया जैसे असावधानियों की आवश्यकता को हटाते हुए, यदि बच्चे की प्रक्रिया समाप्त हो गई थी, तो आप खुद से बाहर निकल सकते sleepहैं। आपकी स्क्रिप्ट में ऐसा करने का एक त्वरित तरीका उपयोग करना है set -e, हालांकि इसके लिए कमांड के लिए कुछ ट्विक्स की आवश्यकता हो सकती है, जिसकी निकास स्थिति एक अपेक्षित नॉनजरो है।


1
सेट-ई बैश में सही तरीके से काम नहीं करता है जब तक कि आप बैश -4 का उपयोग नहीं कर रहे हैं
स्किल

क्या मतलब है "सही ढंग से काम नहीं करता है"? मैं इसे सफलतापूर्वक 3 bash पर उपयोग किया है, लेकिन शायद कुछ किनारे मामले हैं।
टॉम हंट

कुछ सरल मामलों में, बैश 3 ने त्रुटि पर निकास किया। हालांकि सामान्य मामले में ऐसा नहीं हुआ। एक विशिष्ट परिणाम के रूप में, लक्ष्य बनाते समय असफल नहीं हुआ और यह एक ऐसे मेकफाइल से था जो उपनिर्देशिकाओं में लक्ष्य की सूची पर काम करता था। डेविड कॉर्न और मुझे बैश 4 के लिए बग को ठीक करने के लिए मनाने के लिए बैश मेंटेनर के साथ कई सप्ताह मेल करना पड़ा।
स्किल

4
ध्यान दें कि यहाँ समस्या यह है कि pingSIGINT प्राप्त करने पर 0 बाहर निकलने की स्थिति के साथ रिटर्न होता है और bashयदि SIGINT इसे प्राप्त करता है तो इसे अनदेखा कर देता है। "सेट-ई" जोड़ने या बाहर निकलने की स्थिति की जांच करने से यहां मदद नहीं मिलेगी। SIGINT पर एक स्पष्ट जाल जोड़ने से मदद मिलेगी।
स्टीफन चेज़लस

4

टर्मिनल नियंत्रण-सी को नोटिस करता है और INTअग्रभूमि प्रक्रिया समूह को एक संकेत भेजता है , जिसमें यहां शेल भी शामिल है, जैसा pingकि एक नया अग्रभूमि प्रक्रिया समूह नहीं बनाया गया है। फंसने से यह सत्यापित करना आसान है INT

#! /bin/bash
trap 'echo oh, I am slain; exit' INT
while true; do
  ping -c5 127.0.0.1
done

यदि चलाए जा रहे कमांड ने एक नया अग्रभूमि प्रक्रिया समूह बनाया है, तो नियंत्रण-सी उस प्रक्रिया समूह में जाएगा, और शेल में नहीं। उस स्थिति में, शेल को निकास कोड का निरीक्षण करने की आवश्यकता होगी, क्योंकि यह टर्मिनल द्वारा संकेत नहीं दिया जाएगा।

( INTगोले में से निपटने fabulously माध्यम से जटिल जा सकता है, के रूप में खोल कभी कभी संकेत की अनदेखी करने की जरूरत है, और कभी कभी नहीं स्रोत गोता अगर उत्सुक, या Ponder:। tail -f /etc/passwd; echo foo)


इस मामले में, समस्या सिग्नल से निपटने की नहीं है, लेकिन यह तथ्य कि बैश स्क्रिप्ट में जॉबकंट्रोल करता है, हालांकि यह नहीं होना चाहिए, अधिक जानकारी के लिए मेरा जवाब देखें
schily

नई प्रक्रिया समूह में जाने के लिए SIGINT के लिए, कमांड को टर्मिनल का ioctl () भी करना होगा ताकि वह टर्मिनल का अग्रभूमि प्रक्रिया समूह बना सके। pingयहाँ एक नया प्रक्रिया समूह शुरू करने का कोई कारण नहीं है और पिंग का संस्करण (डेबियन पर आईपिल्स) जिसके साथ मैं ओपी की समस्या को पुन: उत्पन्न कर सकता हूं एक प्रक्रिया समूह नहीं बनाता है।
स्टीफन चेजलस

1
ध्यान दें कि यह वह टर्मिनल नहीं है जो SIGINT भेजता है, यह tty डिवाइस (ड्राइवर / कर्नेल में कोड) / dev / ttysomething डिवाइस का लाइन डिसिप्लिन है, जो किसी अनसैप्ड (lnext द्वारा) V वर्ण को प्राप्त करने पर ^ C वर्ण है। टर्मिनल से।
स्टीफन चेज़लस

2

खैर, मैंने sleep 1बैश स्क्रिप्ट में एक जोड़ने की कोशिश की , और बैंग!
अब मैं इसे दो के साथ बंद करने में सक्षम हूं Ctrl+C

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

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

साथ स्क्रिप्ट में sleep 1, इस कॉल के एक सेकंड के लिए निष्पादन को निलंबित कर देगा, और जब से पहले बाधित Ctrl+C(प्रथम SIGINT), subshell अगले आदेश पर अमल करने और समय लगेगा। तो अब, दूसरा Ctrl+C(दूसरा SIGINT) सबस्क्रिप्शन में जाएगा , और स्क्रिप्ट का निष्पादन समाप्त हो जाएगा।


आप गलत हैं, सही ढंग से काम कर रहे शेल पर, एक ^ C पर्याप्त है, पृष्ठभूमि के लिए मेरा उत्तर देखें।
विद्वान

ठीक है, यह देखते हुए कि आपको वोट दिया गया है, और वर्तमान में आपके उत्तर का स्कोर -1 है, मैं बहुत आश्वस्त नहीं हूं कि मुझे आपके उत्तर को गंभीरता से लेना चाहिए।
भतीजे

तथ्य यह है कि कुछ लोगों को नीचा दिखाना हमेशा एक उत्तर की गुणवत्ता से संबंधित नहीं होता है। यदि आपको दो बार ^ c टाइप करने की आवश्यकता है, तो आप निश्चित रूप से बैश बग के शिकार हैं। क्या आपने एक अलग शेल की कोशिश की? क्या आपने असली बॉर्न शेल की कोशिश की?
विद्वान

यदि शेल सही ढंग से काम कर रहा है, तो यह एक स्क्रिप्ट से एक ही प्रक्रिया समूह में सब कुछ चलाता है और फिर एक ^ ^ पर्याप्त है।
विद्वान

1
इस उत्तर में वर्णित व्यवहार @nephewtom को अलग-अलग व्यवहार करने वाले स्क्रिप्ट में अलग-अलग तरीके से समझाया जा सकता है जब वे Ctrl-C प्राप्त करते हैं। यदि एक नींद मौजूद है, तो यह बहुत अधिक संभावना है कि Ctrl-C प्राप्त होगा जबकि नींद निष्पादित हो रही है (लूप में बाकी सब कुछ तेज है)। नींद को मार दिया जाता है, निकास मूल्य 130 के साथ। नींद के जनक, एक खोल, नोटिस जो नींद को सिगिंट द्वारा मार दिया गया था, और बाहर निकलता है। लेकिन अगर स्क्रिप्ट में नींद नहीं है, तो इसके बजाय Ctrl-C पिंग पर जाता है, जो 0 से बाहर निकलकर प्रतिक्रिया करता है, इसलिए पेरेंट शेल अगले कमांड को निष्पादित करता है।
जोनाथन हार्टले

0

इसे इस्तेमाल करे:

#!/bin/bash
while true; do
   echo "Ctrl-c works during sleep 5"
   sleep 5
   echo "But not during ping -c 5"
   ping -c 5 127.0.0.1
done

अब पहली पंक्ति को इसमें बदलें:

#!/bin/sh

और फिर से कोशिश करें - देखें कि क्या पिंग अब रुकावट है।


0
pgrep -f process_name > any_file_name
sed -i 's/^/kill /' any_file_name
chmod 777 any_file_name
./any_file_name

उदाहरण के लिए pgrep -f firefox, चलने का पीआईडी ​​पकड़ लेगा firefoxऔर इस पीआईडी ​​को एक फाइल में सेव करेगा any_file_namekillf sed ’कमांड ile any_file_name’ फ़ाइल में PID नंबर की शुरुआत में जोड़ देगा । तीसरी पंक्ति any_file_nameनिष्पादन योग्य फ़ाइल करेगी । अब आगे की लाइन फाइल में उपलब्ध PID को मार देगी any_file_name। किसी फ़ाइल में उपरोक्त चार लाइनें लिखना और उस फ़ाइल को निष्पादित करना Control- कर सकते हैं C। मेरे लिए बिल्कुल ठीक काम करना।


0

अगर किसी को इस bashसुविधा के लिए तय करने में दिलचस्पी है , और इसके पीछे दर्शन में इतना नहीं है, तो यहां एक प्रस्ताव है:

समस्याग्रस्त कमांड को सीधे न चलाएं, लेकिन एक रैपर से जो कि a) इसके लिए इंतजार करता है b को समाप्त करने के लिए) संकेतों और c के साथ गड़बड़ नहीं करता है) WCE तंत्र को स्वयं लागू नहीं करता है, लेकिन बस एक प्राप्त करने पर मर जाता है SIGINT

इस तरह के रैपर को awk+ system()फंक्शन के साथ बनाया जा सकता है ।

$ while true; do awk 'BEGIN{system("ping -c5 localhost")}'; done
PING localhost(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.087 ms
^C
--- localhost ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1022ms
rtt min/avg/max/mdev = 0.082/0.084/0.087/0.009 ms
[3]-  Terminated              ping -c5 localhost

ओपी की तरह एक स्क्रिप्ट में रखो:

#!/bin/bash
while true; do
        echo -e "\n*** DATE:" `date` " ***";
        echo "********************************************"
        awk 'BEGIN{system(ARGV[1])}' "ping -c5 ${1-localhost}"
done

-3

आप एक प्रसिद्ध बैश बग के शिकार हैं। बैश स्क्रिप्ट के लिए जॉबकंट्रोल करता है जो एक गलती है।

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

सत्यापित करने के लिए: हाल के बॉर्न शेल को प्राप्त करें और संकलित करें जो एक प्रोग्राम के रूप में pgrp (1) को लागू करता है, फिर स्क्रिप्ट लूप में एक / बिन / नींद 100 (या अपने मंच के आधार पर usr / बिन / नींद) जोड़ें और शुरू करें बॉर्न शेल। जब आप स्लीप कमांड के लिए प्रक्रिया आईडी प्राप्त करने के लिए ps (1) का उपयोग pgrp <pid>करते हैं और स्क्रिप्ट चलाने वाले बैश, नींद की प्रक्रिया आईडी द्वारा "<pid>" को कॉल और प्रतिस्थापित करते हैं और स्क्रिप्ट को चलाने वाले बैश को। आपको अलग-अलग प्रक्रिया समूह आईडी दिखाई देंगे। अब कुछ इस तरह से कॉल करें pgrp < /dev/pts/7(स्क्रिप्ट द्वारा उपयोग किए जाने वाले ट्टी नाम की जगह) को मौजूदा tty प्रक्रिया समूह प्राप्त करें। TTY प्रक्रिया समूह नींद कमांड के प्रक्रिया समूह के बराबर है।

ठीक करने के लिए: एक अलग शेल का उपयोग करें।

हाल के बॉर्न शैल स्रोत मेरे विद्वान उपकरण पैकेज में हैं, जो आप यहां पा सकते हैं:

http://sourceforge.net/projects/schilytools/files/


वह कौन सा संस्करण bashहै? AFAIK bashकेवल यही करता है कि यदि आप -m या -i विकल्प पास करते हैं।
स्टीफन चेज़लस 14

ऐसा लगता है कि यह अब bash4 पर लागू नहीं होता है, लेकिन जब ओपी को इस तरह की समस्या होती है, तो वह bash3 का उपयोग करने लगता है
schily

Bash3.2.48 और न ही bash 3.0.16 और न ही bash-2.05b के साथ पुन: पेश नहीं किया जा सकता (साथ की कोशिश की bash -c 'ps -j; ps -j; ps -j')।
स्टीफन चेजलस 15

यह निश्चित रूप से तब होता है जब आप बैश को कॉल करते हैं /bin/sh -ce। मुझे एक बदसूरत वर्कअराउंड जोड़ना पड़ा, smakeजो कि वर्तमान में चल रहे कमांड के लिए प्रक्रिया समूह ^Cको एक लेयर मेक कॉल को खत्म करने की अनुमति देने के लिए प्रक्रिया समूह को मारता है । क्या आपने जाँच की कि क्या bash प्रक्रिया समूह आईडी से प्रक्रिया समूह को बदल दिया गया था जिसके साथ यह आरंभ किया गया था?
स्किल

ARGV0=sh bash -ce 'ps -j; ps -j; ps -j'सभी 3 पीएस इनवोकेशन में ps और bash के लिए एक ही pgid रिपोर्ट करता है। (ARGV0 = श zshargv को पार करने का तरीका है [को ०])।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.