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?

War es hilfreich?

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top