Terminalde loop bash betiğini nasıl durdurabilirim?


54

Örneğin,

#!/bin/bash
while :
do
    sl
done

Bu bash betiğini nasıl sonlandırabilirim?


1
Daha fazla ayrıntı ver. Etkileşimli veya programatik olarak durdurmak ister misiniz?
Manatwork 17:12

1
Sinyali ctrl-cgöndermek için basabilirsiniz SIGINT(çoğu kabukta) veya Sinyali ctrl-zgöndermek için basabilirsiniz SIGTSTP(çoğu kabukta). Bastığınız durumda ctrl-zilgili işlem öldürülmez, duraklatılır. fg(En azından içinde bash) ile devam edebilirsiniz
user1146332 17:12

Hayır, çalışmıyor!
Yinyanghu

4
Sorun senaryo değil, slinanıyorum ki, yanlış yazanlar için lsyavaşça geçen bir tren gösteren can sıkıcı bir komut . Bildiğim kadarıyla SIGINTsinyalleri hapseder ve birlikte öldürülmesi gerekir SIGKILL.

1
Teşekkürler. Dağıtımım için hazırlanmadım, bu yüzden bilmiyordum / buldum. (Sanırım bunun için bir ricada
bulunmayacağım

Yanıtlar:


64

Program slbilerek yok sayar SIGINT, bu nedenle bastığınızda ne gönderilir Ctrl+C. Bu nedenle, öncelikle, argümanı ekleyerek slyoksaymamayı söylemeniz gerekir .SIGINT-e

Bunu denerseniz, her bir kişiyi durdurabileceğinizi fark edeceksiniz sl, ancak yine de tekrar ediyorlar. Sonra bashda çıkmayı söylemelisin SIGINT. Bunu trap "exit" INTdöngüden önce koyarak yapabilirsiniz .

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

5
Ben kontrol etmek yüklü olmayan, ama sen de Ctrl- \ dan SIGQUIT ile öldürmek mümkün olabilir
derobert

120
  1. Ctrl-Zbetiği askıya almak için basın
  2. kill %%

%%Bash yerleşik söyler killsen bir süreç id, cari kabuğunda en son asılı arka plan işi için bir sinyal (varsayılan olarak SIGTERM) göndermek istediğiniz.

Ayrıca işleri numaraya veya isme göre de belirleyebilirsiniz. örneğin, ^ Z ile bir işi askıya aldığınızda, bash size iş numarasının nasıl bir şey olduğunu, köşeli parantezlerin içinde iş numarasının [n]+ Stoppednerede olduğunu söyleyecektir n.

Koşmak iş kumandada ve öldürme işler hakkında daha fazla bilgi için help jobs, help fg, help bg, ve help killbash ve aramak JOB CONTROL(bütün kapaklar) veya jobspecbash adam sayfasında.

Örneğin

$ ./killme.sh 
./killme.sh: satır 4: sl: komut bulunamadı
./killme.sh: satır 4: sl: komut bulunamadı
./killme.sh: satır 4: sl: komut bulunamadı
./killme.sh: satır 4: sl: komut bulunamadı
./killme.sh: satır 4: sl: komut bulunamadı
...
...
...
./killme.sh: satır 4: sl: komut bulunamadı
^ Z
[1] + Durduruldu.
$ %% öldür
$ 
[1] + Sonlandırıldı.

Bu örnekte, işin numarası kill %11'di;kill %%

(NOT: slYüklemedim, bu nedenle çıktı yalnızca "komut bulunamadı" dır. Sizin durumunuzda, sl çıktısı ne olursa olsun elde edersiniz. Önemli değil - ^Zaskıya alma kill %%işlemi aynı şekilde çalışır)


3
Başka bir iyi cevap!
Yinyanghu

2
BTW, bu gibi döngüleri hızla uygulamak için, ^ Z, işlemi öldürmenin ^ C'den daha güvenilir bir yolu olabilir. ^ C sl, döngüde çalıştırılan programa ( ) gönderilir , ancak komut dosyası çalışmaya devam eder ... ve bir başkasını başlatır sl. Eğer ^ C tuşuna çok hızlı basarsanız, hem slbetiği hem de senaryoyu öldürebilirsiniz (eğer ikisi de SIGINT'i yakalamazsa). ^ Z komut dosyasını neredeyse hemen askıya alır (hemen terminalinize yazdırılan arabellekli çıktıyı saymazsanız hemen), bu nedenle ile öldürebilirsinizkill %%
cas

Kesinlikle! " slEğlenceli bir program" demek zorundayım . Bu sefer, yine beni eğlenceli! @ _ @
Yinyanghu 18:12

Yalnızca döngü bir komut dosyasından değil, doğrudan komut satırından çağrıldığında da işe yarayan görünen yanıt.
Skippy le Grand Gourou,

1
@DrewChapin Ne zaman / nerede öğrendiğimi hatırlayamıyorum - sadece "sonsuza dek" bildiğim bir şey. Bash adam sayfası (aramak jobspec ) diyor ki: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
cas

6

Ctrl + c'nin döngüyü durdurmasını ancak komut dosyasını sonlandırmamasını || breakistiyorsanız, çalıştırdığınız komuttan sonra yerleştirebilirsiniz . Çalıştırdığınız program ctrl + c ile sonlandırıldığı sürece, bu harika çalışıyor.

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

Yuvalanmış bir döngü içindeyseniz, iki seviyeden çıkmak için "break 2" kullanabilirsiniz.


artı 2 mola için 1
flyingfinger

3

Bu betiği, bu betiği başlattığınız terminalden Ctrl + C tuşlarına basarak sonlandırabilirsiniz. Tabii ki bu betiğin ön planda çalışması gerekir, böylece Ctrl + C ile durdurabilirsiniz.

Veya bu betiğin PID'sini (İşlem Kimliği) diğer açılan terminalde aşağıdaki yollarla bulabilirsiniz:

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

Her iki yol da istediğin numarayı yapmalı.


1
Terminalden Ctrl + C ile sonlandırılamaz. Bu yüzden ps veya üst tarafından öldürmek zorundayım. Sadece nasıl doğrudan öldürüleceğini bilmek istiyorum!
Yinyanghu 17:12

3

En kolay yol QUIT, genellikle bağlı olan sinyali vermektir Control-Backslash.

Treni gördüğünüzde, Control- \


1

Şunları yapabilirsiniz kabuğun (bash). Sadece denedim ve işe yarıyor. Çünkü (döngü döngüsünde çalıştırdığımız işten) gelen süreci göremiyorum .killpid

ps -ef


0

Komut dosyasının tamamını sonlandırmanın başka bir yolu da slkomutun arka planını oluşturmak ve ardından INTkomut dosyasının tüm işlem grubunu sinyalle öldürmek için sinyali yakalamaktır 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

bu yardımcı olmalı.


2
Neden son arka plan komutunun PID'inin 0 olacağını düşünüyorsunuz?
Manat çalışması

-1

Öldürme olayı berbat, çünkü senaryo iki kez çalıştırılmak zorunda kalmadıysa, şimdi asla. VE çıkış kodunuz yanlış.

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

Çalışmak yok. Çözüm = perl kullanın. kendi bashını açar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.