Wie nach der Tötung in bash Terminated Nachricht zu unterdrücken?
Frage
Wie kann man die Terminated
Meldung zu unterdrücken, die aufkommt, nachdem Sie ein töten
Prozess in einem Bash-Skript?
Ich habe versucht set +bm
, aber das funktioniert nicht.
Ich weiß, dass eine andere Lösung beinhaltet exec 2> /dev/null
nennen, aber ist, dass
zuverlässig? Wie kann ich es wieder zurückgesetzt, so dass ich auch weiterhin stderr sehen?
Lösung
Die kurze Antwort ist, dass Sie nicht können. Bash druckt immer den Status Vordergrund Arbeitsplätze. Die Überwachung Flag gilt nur für Hintergrundjobs, und nur für interaktiv Shell, keine Skripts.
siehe notify_of_job_status () in jobs.c.
Wie Sie sagen, können Sie umleiten so Standardfehler zeigt auf / dev / null, aber dann verpassen Sie weitere Fehlermeldungen. Sie können es vorübergehend, indem sie die Umleitung in einer Subshell zu tun, die das Skript ausgeführt wird. Dies läßt die ursprüngliche Umgebung allein.
(script 2> /dev/null)
, die alle Fehlermeldungen verlieren, aber nur aus diesem Skript, nicht von allem anderen Laufe in dieser Shell.
Sie können Standardfehler speichern und wiederherstellen, indem Sie einen neuen FileDescriptor Umleitung dort Punkt:
exec 3>&2 # 3 is now a copy of 2
exec 2> /dev/null # 2 now points to /dev/null
script # run script with redirected stderr
exec 2>&3 # restore stderr to saved
exec 3>&- # close saved version
Aber ich würde nicht empfehlen - der einzige Vorteil von dem ersten ist, dass es eine Unterschale Aufruf speichert, während sie komplizierter und möglicherweise sogar das Verhalten des Skripts zu ändern, wenn die Skriptdatei Deskriptoren verändert .
EDIT:
Weitere passende Antwort Antwortkontrolle von Mark Edgar gegeben
Andere Tipps
Um die Nachricht zum Schweigen zu bringen, müssen Sie stderr
zu der Zeit werden Umleitung der Nachricht erzeugt wird, . Da der kill
Befehl ein Signal sendet und wartet nicht auf den Zielprozess zu reagieren, stderr
Umleitung des kill
Befehl tut dir nicht gut. Die bash gebautet wait
wurde speziell für diesen Zweck hergestellt.
Hier ist sehr einfaches Beispiel, das den letzten Hintergrund Befehl tötet. ( mehr über $ Erfahren Sie hier,. )
kill $!
wait $! 2>/dev/null
Da sowohl kill
und wait
mehrere pids akzeptieren, können Sie auch tun Batch kills. Hier ist ein Beispiel, das alle Hintergrundprozesse tötet (des aktuellen Prozesses / script natürlich).
kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null
Ich habe hier geführt von bash: leise Hintergrundfunktion Prozess beenden .
Inspiriert von MARCH Antwort . Ich war mit kill -INT
als er mit einigem Erfolg schon sagt, aber ich merkte, dass es nicht einige Prozesse tötet. einige andere Signale Nach dem Test Ich sehe, dass SIGPIPE
ohne Botschaft auch töten.
kill -PIPE
oder einfach
kill -13
Lösung: Verwenden Sie SIGINT (funktioniert nur in nicht-interaktiven Shells)
Demo:
cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF
sh silent.sh
http://thread.gmane.org/gmane.comp. shells.bash.bugs / 15798
Vielleicht durch den Aufruf disown
den Prozess von dem aktuellen Shell-Prozess lösen?
Ist das, was wir alle suchen?
Nicht gesucht:
$ sleep 3 &
[1] 234
<pressing enter a few times....>
$
$
[1]+ Done sleep 3
$
Gesucht:
$ (set +m; sleep 3 &)
<again, pressing enter several times....>
$
$
$
$
$
Wie Sie sehen können, keine Job-Ende-Nachricht. Funktioniert bei mir in Bash-Skripte als gut, auch für Hintergrundprozesse getötet.
'gesetzt + m' deaktiviert Auftragssteuerung (siehe 'Hilfe-Set') für den aktuell Shell. Also, wenn Sie Ihren Befehl in einer Subshell eingeben (wie hier in Klammern getan) werden Sie nicht die Kontrolle Auftragseinstellungen Einfluss der aktuellen Shell. Einziger Nachteil ist, dass Sie die pid des Hintergrundprozesses zurück in der aktuellen Shell erhalten müssen, wenn Sie, ob es beendet hat überprüfen möchten, oder den Return-Code bewerten.
Eine weitere Möglichkeit, Job-Benachrichtigungen zu deaktivieren, ist Ihr Befehl in einem sh -c 'cmd &'
Konstrukt backgrounded werden.
#!/bin/bash
# ...
pid="`sh -c 'sleep 30 & echo ${!}' | head -1`"
kill "$pid"
# ...
# or put several cmds in sh -c '...' construct
sh -c '
sleep 30 &
pid="${!}"
sleep 5
kill "${pid}"
'
Das funktioniert auch für killall (für diejenigen, die es vorziehen):
killall -s SIGINT (yourprogram)
unterdrückt die Nachricht ... Ich war mpg123 im Hintergrundmodus ausgeführt wird. Es konnte nur leise durch das Senden einer ctrl-c (SIGINT) anstelle eines SIGTERM (default) getötet werden.
disown tat genau das Richtige für mich - die exec 3> & 2 ist für eine Vielzahl von Gründen riskant - Satz + bm offenbar nicht in einem Skript arbeiten, nur an der Eingabeaufforderung
Wir hatten Erfolg mit dem Hinzufügen von ‚jobs 2>&1 >/dev/null
‘, um das Skript, nicht sicher, ob es jemand anderes Skript helfen, aber hier ist ein Beispiel.
while true; do echo $RANDOM; done | while read line
do
echo Random is $line the last jobid is $(jobs -lp)
jobs 2>&1 >/dev/null
sleep 3
done
Ich fand, dass in Abhängigkeit des Kill-Befehl setzen und dann die Funktion Hintergrund versetzen die Beendigung Ausgabe unterdrückt
function killCmd() {
kill $1
}
killCmd $somePID &
Ganz einfach:
{ kill $! } 2>/dev/null
Vorteil? kann jedes Signal
ex:
{ kill -9 $PID } 2>/dev/null