Wie sende ich control + c aus einem Bash-Skript?


71

Ich starte eine Reihe von Bildschirmen in einem Bash-Skript und führe dann runserverin jedem von ihnen den Befehl von django aus. Ich möchte programmatisch können , sie alle als gut stoppen, was mich erfordert zu senden Control+can runserver.

Wie kann ich diese Tastenanschläge aus meinem Bash-Skript senden?


Antworten:


90

Ctrl+Csendet ein SIGINTSignal.

kill -INT <pid>sendet auch ein SIGINTSignal:

# Terminates the program (like Ctrl+C)
kill -INT 888
# Force kill
kill -9 888

Angenommen, es 888ist Ihre Prozess-ID.


Beachten Sie, dass kill 888ein SIGTERMSignal gesendet wird, das sich geringfügig unterscheidet, aber auch zum Stoppen des Programms auffordert. Wenn Sie also wissen, was Sie tun (kein SIGINTim Programm gebundener Handler ), reicht ein einfacher killaus.

Verwenden Sie Folgendes, um die PID des zuletzt in Ihrem Skript gestarteten Befehls abzurufen $!:

# Launch script in background
./my_script.sh &
# Get its PID
PID=$!
# Wait for 2 seconds
sleep 2
# Kill it
kill $PID

5
Per man kill: Wenn kein Signal angegeben ist, wird das TERM-Signal gesendet , also kill $PIDnicht SIGINTan den Prozess gesendet und ist daher nicht dasselbe wie Strg + C-Tastaturereignis
Alex

@ Alex Guter Fang! Ich glaube zwar nicht, dass es einen praktischen Unterschied gibt, aber ich kann mich irren.
Matthieu Napoli

Abhängig vom Befehl kann es anders sein, wenn ein Handler für SIGTERM oder SIGINT installiert ist. Wie auch immer, wie @paxdiablo sagt, Verwendung kill -INT, kill -SIGINToder kill -2.
Domen

@domen richtig, ich habe die Antwort aktualisiert, damit sie genauer ist.
Matthieu Napoli

hängt davon ab, ob Sie den Befehl Strg + C als Eingabe an einen anderen Prozess senden möchten.
16.

14

CTRL-C sendet im Allgemeinen ein SIGINT-Signal an den Prozess, sodass Sie einfach Folgendes tun können:

kill -INT <processID>

über die Befehlszeile (oder ein Skript), um die spezifischen zu beeinflussen processID.

Ich sage "allgemein", weil dies, wie bei den meisten UNIX-Programmen, nahezu unendlich konfigurierbar ist. Wenn Sie ausführen stty -a, können Sie sehen, welche Tastenfolge mit dem intrSignal verbunden ist. Dies wird wahrscheinlich sein, CTRL-Caber diese Tastenfolge kann vollständig auf etwas anderes abgebildet werden.


Die folgende Skript zeigt diese in Aktion (wenn auch mit TERMnicht INTda sleepreagiert nicht auf INTin meiner Umgebung):

#!/usr/bin/env bash

sleep 3600 &
pid=$!
sleep 5

echo ===
echo PID is $pid, before kill:
ps -ef | grep -E "PPID|$pid" | sed 's/^/   /'
echo ===

( kill -TERM $pid ) 2>&1
sleep 5

echo ===
echo PID is $pid, after kill:
ps -ef | grep -E "PPID|$pid" | sed 's/^/   /'
echo ===

Grundsätzlich wird ein Stundenprotokollprozess gestartet sleepund die Prozess-ID abgerufen. Anschließend werden die relevanten Prozessdetails ausgegeben, bevor der Prozess abgebrochen wird.

Nach einer kurzen Wartezeit wird die Prozesstabelle überprüft, um festzustellen, ob der Prozess abgeschlossen ist. Wie Sie der Ausgabe des Skripts entnehmen können, ist es tatsächlich weg:

===
PID is 28380, before kill:
   UID   PID     PPID    TTY     STIME      COMMAND
   pax   28380   24652   tty42   09:26:49   /bin/sleep
===
./qq.sh: line 12: 28380 Terminated              sleep 3600
===
PID is 28380, after kill:
   UID   PID     PPID    TTY     STIME      COMMAND
===

Wie kann ich das pidvon einem bestimmten Prozess wie Tomcat
Manoj

2

ctrl+ cund kill -INT <pid>sind nicht genau gleich , um ctrl+ zu emulieren c, müssen wir zuerst den Unterschied verstehen.

kill -INT <pid>sendet das INTSignal an einen bestimmten Prozess (gefunden mit seinem pid).

ctrl+ cwird dem intrSonderzeichen zugeordnet, das beim Empfang durch das Terminal INTan die Vordergrundprozessgruppe dieses Terminals gesendet werden soll. Sie können dies emulieren, indem Sie auf die Gruppe Ihres Gegebenen abzielen <pid>. Dies kann durch Voranstellen eines -vor dem Signal im Befehl kill erfolgen. Daher lautet der gewünschte Befehl:

kill -INT -<pid>

Sie können es ziemlich einfach mit einem Skript testen:

#!/usr/bin/env ruby

fork {
    trap(:INT) {
        puts 'signal received in child!'
        exit
    }
    sleep 1_000
}

puts "run `kill -INT -#{Process.pid}` in any other terminal window."
Process.wait

Quellen:


0

Sie können die PID eines bestimmten Prozesses wie MySQL mithilfe der folgenden Befehle abrufen: ps -e | pgrep mysql

Dieser Befehl gibt Ihnen die PID des MySQL-Prozesses. Beispiel: 13954 Geben Sie nun den folgenden Befehl auf dem Terminal ein. kill -9 13954 Dies beendet den Prozess von MySQL.


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

Beispiel: 'pgrep -f Firefox' ermittelt die PID für die Ausführung von 'Firefox' und speichert diese PID in einer Datei mit dem Namen 'any_file_name'. Der Befehl 'sed' fügt das 'kill' am Anfang der PID-Nummer in die Datei 'any_file_name' ein. In der dritten Zeile wird die Datei 'any_file_name' ausführbar. In der vierten Zeile wird die in der Datei 'any_file_name' verfügbare PID gelöscht. Das Schreiben der obigen vier Zeilen in eine Datei und das Ausführen dieser Datei kann das Steuerelement-C ausführen. Funktioniert absolut gut für mich.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.