टर्मिनल में लूप बैश स्क्रिप्ट को कैसे रोकें?


54

उदाहरण के लिए,

#!/bin/bash
while :
do
    sl
done

इस बैश स्क्रिप्ट को कैसे समाप्त किया जाए?


1
अधिक जानकारी दें। क्या आप इसे संवादात्मक या प्रोग्रामेटिक रूप से रोकना चाहते हैं?
15

1
आप सिग्नल ctrl-cभेजने के लिए प्रेस कर सकते हैं SIGINT(अधिकांश गोले में) या आप उस प्रेस ctrl-zको भेज सकते हैं जो SIGTSTPसिग्नल भेजता है (अधिकांश गोले में)। मामले में आप ctrl-zसंबंधित प्रक्रिया को दबाया नहीं मारा जाता है, लेकिन रोक दिया जाता है। आप इसे fg(कम से कम bash)
user1146332

नहीं, यह काम नहीं करता है!
यिनगांशु

4
समस्या स्क्रिप्ट नहीं है, लेकिन slमैं जो आदेश मानता हूं, वह उन लोगों के लिए एक एनोइंग कमांड है, जो lsट्रेन को धीरे-धीरे गुजरते हुए दिखाते हैं। जहां तक ​​मुझे पता है कि यह SIGINTसिग्नल को फंसाता है और इसे मारना चाहिए SIGKILL

1
धन्यवाद। मेरे डिस्ट्रो के लिए पैक नहीं किया गया, इसीलिए मैं इसे नहीं जानता / पाया। (मुझे लगता है कि मैं इसके लिए कोई अनुरोध दर्ज नहीं करूंगा।)
मैनटवर्क

जवाबों:


64

कार्यक्रम slजानबूझकर नजरअंदाज करता है SIGINT, जो कि प्रेस करते समय भेजा जाता है Ctrl+C। इसलिए, सबसे पहले, आपको तर्क को जोड़कर slअनदेखा नहीं करना होगा ।SIGINT-e

यदि आप यह कोशिश करते हैं, तो आप देखेंगे कि आप प्रत्येक व्यक्ति को रोक सकते हैं sl, लेकिन वे अभी भी दोहराते हैं। साथ ही bashबाहर निकलने के लिए आपको बताना होगा SIGINT। आप trap "exit" INTलूप से पहले लगाकर ऐसा कर सकते हैं ।

#!/bin/bash
trap "exit" INT
while :
do
    sl -e
done

5
मैं यह जाँच करने के लिए स्थापित नहीं है, लेकिन आप यह भी SIGQUIT के साथ मारने के लिए Ctrl- \ से सक्षम हो सकता है
derobert

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

%%बैश में निर्मित बताता है killकि आप वर्तमान खोल में सबसे हाल ही में निलंबित पृष्ठभूमि काम के लिए एक संकेत (डिफ़ॉल्ट रूप से SIGTERM) भेजने के लिए, एक प्रक्रिया आईडी नहीं करना चाहता।

आप संख्या या नाम से भी नौकरियों को निर्दिष्ट कर सकते हैं। उदाहरण के लिए, जब आप ^ Z के साथ किसी नौकरी को निलंबित करते हैं, तो bash आपको बताएगा कि उसकी नौकरी का नंबर कुछ इस तरह से है [n]+ Stopped, जहाँ nवर्ग कोष्ठक के अंदर का कार्य नंबर है।

काम पर नियंत्रण पर और की मौत हो गई नौकरियों के बारे में अधिक जानकारी के लिए, चलाने के लिए help jobs, help fg, help bg, और help killपार्टी में, और के लिए खोज JOB CONTROL(सभी टोपियां) या jobspecबैश आदमी पेज में।

जैसे

$ ./killme.sh 
./killme.sh: पंक्ति 4: sl: कमांड नहीं मिली
./killme.sh: पंक्ति 4: sl: कमांड नहीं मिली
./killme.sh: पंक्ति 4: sl: कमांड नहीं मिली
./killme.sh: पंक्ति 4: sl: कमांड नहीं मिली
./killme.sh: पंक्ति 4: sl: कमांड नहीं मिली
...
...
...
./killme.sh: पंक्ति 4: sl: कमांड नहीं मिली
^ Z
[१] + रुका हुआ ।/killme.sh
$ मार %%
$ 
[१] + समाप्त हो गया ।/killme.sh

इस उदाहरण में, नौकरी का नंबर 1 था, इसलिए kill %1उसी के अनुसार काम किया होगाkill %%

(नोट: मैंने slस्थापित नहीं किया है, इसलिए आउटपुट सिर्फ "कमांड नहीं मिला" है। आपके मामले में, आपको जो भी आउटपुट स्ल उत्पन्न होता है, ^Zवह kill %%मिलेगा - यह महत्वपूर्ण नहीं है - सस्पेंड और वही काम करेगा)


3
एक और अच्छा जवाब!
यिनगांशु

2
BTW, तेजी से इस तरह से निष्पादित करने के लिए, ^ ^ ^ C से प्रक्रिया को मारने के लिए Z एक अधिक विश्वसनीय तरीका हो सकता है। ^ सी को slलूप में चलाए जा रहे प्रोग्राम ( ) में भेजा जाएगा , लेकिन स्क्रिप्ट चलती रहेगी ... और दूसरी शुरू करें sl। यदि आप ^ C वास्तव में तेजी से कुछ बार दबाते हैं, तो आपको slऔर स्क्रिप्ट दोनों को मारने के लिए मिल सकता है (यदि उनमें से कोई भी SIGINT नहीं फंसता है)। ^ Z लगभग तुरंत ही स्क्रिप्ट को निलंबित कर देगा (तुरंत यदि आप बफर आउटपुट की गणना नहीं करते हैं जो अभी भी आपके टर्मिनल पर प्रिंट किया जा रहा है), तो आप इसे मार सकते हैंkill %%
पीएस

ठीक ठीक! मुझे कहना है " slएक मजेदार कार्यक्रम है"। इस बार, यह मुझे फिर से मज़ा! @ _ @
यिनगांशु

केवल वह उत्तर जो काम करने लगता है, जब लूप को स्क्रिप्ट से नहीं बल्कि सीधे कमांड लाइन से बुलाया जाता है।
स्कीपी ले ग्रैंड गौरू

1
@ ड्रूचपिन मुझे याद नहीं हो सकता है कि कब / कहाँ मुझे इसके बारे में पता चला - बस कुछ ऐसा है जिसे मैंने "हमेशा के लिए" जाना है। बैश मैन पेज ( जॉबस्पेक की खोज ) कहता है:The symbols %% and %+ refer to the shell's notion of the current job, which is the last job stopped while it was in the foreground or started in the background. The previous job may be referenced using %-. If there is only a single job, %+ and %- can both be used to refer to that job
कैस

6

यदि आप लूप को बंद करने के लिए ctrl + c चाहते हैं, लेकिन स्क्रिप्ट को समाप्त नहीं करते हैं, तो आप || breakजो भी कमांड चला रहे हैं उसके बाद रख सकते हैं। जब तक आप जिस प्रोग्राम को ctrl + c पर समाप्त कर रहे हैं, यह बहुत अच्छा है।

#!/bin/bash
while :
do
    # ctrl+c terminates sl, but not the shell script
    sl -e || break
done

यदि आप नेस्टेड लूप में हैं, तो आप दो स्तरों से बाहर निकलने के लिए "ब्रेक 2" का उपयोग कर सकते हैं, आदि।


प्लस 1 ब्रेक 2 के लिए
फ्लाइंगफिंगर 19

3

आप उस स्क्रिप्ट को टर्मिनल से Ctrl + C दबाकर समाप्त कर सकते हैं जहां आपने यह स्क्रिप्ट शुरू की थी। बेशक यह स्क्रिप्ट अग्रभूमि में चलना चाहिए ताकि आप इसे Ctrl + C द्वारा रोक सकें।

या आप उस स्क्रिप्ट के पीआईडी ​​(प्रोसेस आईडी) को अन्य ओपन टर्मिनल में पा सकते हैं:

ps -ef | grep <name_of_the_script>
kill -9 <pid_of_your_running_script>

दोनों तरीकों से वह चाल चलनी चाहिए जो आप पूछ रहे हैं।


1
इसे टर्मिनल से Ctrl + C द्वारा समाप्त नहीं किया जा सकता है। तो मुझे इसे ps या top से मारना होगा। मैं बस यह जानना चाहता हूं कि इसे सीधे कैसे मारना है!
यिनगांशु

3

सबसे आसान तरीका QUITसिग्नल जारी करना है, जो आमतौर पर जुड़ा होता है Control-Backslash

जब आप ट्रेन देखते हैं, तो Control- \ मारा


1

आप कर सकते हैं खोल के (बैश)। मैंने बस कोशिश की और यह काम करता है। क्योंकि मैं उस प्रक्रिया को नहीं देख सकता (जो काम हम लूपिंग स्क्रिप्ट में चलाते हैं)।killpid

ps -ef


0

पूरी स्क्रिप्ट को समाप्त करने का दूसरा तरीका यह होगा कि slकमांड को बैकग्राउंड किया जाए और फिर सिग्नल INTकी पूरी प्रक्रिया समूह को सिग्नल से मारने के लिए ट्रैप सिग्नल दिया जाए HUP

#!/bin/bash

trap 'trap - INT; kill -s HUP -- -$$' INT
#trap 'trap - INT; kill -s HUP 0' INT

while :
do
   sl & wait
done


-1
while [ true ] 
do

  #check if script is running
  ps | grep script_name.sh | grep -v grep >/dev/null 2>&1

  if [ "$!" != "0" ] ; then
    break
  else

    kill -9 ` ps -ef | grep script_name.sh | cut -d "a" -f 1` 
    echo "kill -9 `get script PID`"

  fi

done

यह मदद करनी चाहिए।


2
आपको क्या लगता है कि अंतिम पृष्ठभूमि कमांड का पीआईडी ​​कभी 0 होगा?
मैनटवर्क

-1

हत्या की बात भयानक है, क्योंकि आप अब कभी नहीं, अगर स्क्रिप्ट को दो बार चलाना है। और आपका निकास कोड गलत है।

while [ something ]; do

 if [ somethingelse ]; then
   echo shut down script with exit code 0
   exit 0
 fi
done

echo something else not happend
exit 2 # Return val important for example for monitoring

काम नहीं कर रहा। समाधान = प्रति उपयोग। जबकि खुद की बकवास खोलता है

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