Es ist ziemlich einfach, einen Prozess im Hintergrund in Bash auszuführen.
$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+ Done echo "Hello I'm a background task"
Die Ausgabe ist jedoch ausführlich. In der ersten Zeile werden die Job-ID und die Prozess-ID der Hintergrundaufgabe gedruckt, dann haben wir die Ausgabe des Befehls, schließlich haben wir die Job-ID, ihren Status und den Befehl, der den Job ausgelöst hat.
Gibt es eine Möglichkeit, die Ausgabe einer Hintergrundaufgabe so zu unterdrücken, dass die Ausgabe genauso aussieht wie ohne das kaufmännische Und am Ende? Dh:
$ echo "Hello I'm a background task" &
Hello I'm a background task
Der Grund, den ich frage, ist, dass ich einen Hintergrundprozess als Teil eines Tab-Vervollständigungsbefehls ausführen möchte, sodass die Ausgabe dieses Befehls nicht unterbrochen werden muss, um einen Sinn zu ergeben.
bash
bash-completion
Alex Spurling
quelle
quelle
Antworten:
Nicht im Zusammenhang mit der Fertigstellung, aber Sie können diese Ausgabe unterdrücken, indem Sie den Aufruf in eine Subshell einfügen:
(echo "Hello I'm a background task" &)
quelle
wait
der Hintergrundjob abgeschlossen werden soll.Aufbauend auf der Antwort von @ shellter funktionierte dies für mich:
tyler@Tyler-Linux:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1; Hello I'm a background task tyler@Tyler-Linux:~$
Ich kenne die Gründe dafür nicht, aber ich erinnerte mich an einen alten Beitrag, der durch Verleugnung verhindert, dass Bash die Prozess-IDs ausgibt.
quelle
;
am Ende hinzugefügt . (ohne Schlaf) . 2. ABER bemerkt, dass, als ichecho STDERR 2>&1
in der "nächsten" Zeile hinzufügte , das[1]+ Done ...
Ding erschien! . 3. Meine Lösung (wie ich jetzt bemerkt habe) funktioniert inksh
undecho STDERR 2>&1
erzeugt nur die Ausgabe STDERR. Nun, lebe und lerne für uns beide. Allen viel Glück.In einigen neueren Versionen von bash und in ksh93 können Sie es mit einer Sub-Shell oder einer Prozessgruppe (dh
{ ... }
) umgeben./home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null Hello I'm a background task /home/shellter $
quelle
ksh93+
als meine primäre Shell verwende. Dieser Code funktioniert wie in ksh versprochen. aber da das OP mit markiert ist,bash
verstehe ich Ihren dv. Die Ergebnisse der Bash-Tests finden Sie in der Antwort von @ Tyzoid. Allen viel Glück!wait $!
was bei der akzeptierten Antwort nicht der Fall zu sein scheint.Aufbauend auf der obigen Antwort, wenn Sie zulassen möchten, dass stderr vom Befehl durchkommt:
f() { echo "Hello I'm a background task" >&2; } { f 2>&3 &} 3>&2 2>/dev/null
quelle
disown
bestimmten Umständen eine .Basierend auf dieser Antwort habe ich mir das prägnantere und korrektere ausgedacht:
silent_background() { { 2>&3 "$@"& } 3>&2 2>/dev/null disown &>/dev/null # Prevent whine if job has already completed } silent_background date
quelle
Versuchen:
user@host:~$ read < <( echo "Hello I'm a background task" & echo $! ) user@host:~$ echo $REPLY 28677
Und Sie haben sowohl den Ausgang als auch die PID ausgeblendet . Beachten Sie, dass Sie die PID weiterhin von $ REPLY abrufen können
quelle
Entschuldigen Sie die Antwort auf einen alten Beitrag, aber ich denke, dies ist für andere nützlich und es ist die erste Antwort bei Google.
Ich hatte ein Problem mit dieser Methode (Subshells) und der Verwendung von 'wait'. Da ich es jedoch in einer Funktion ausführte, konnte ich Folgendes tun:
function a { echo "I'm background task $1" sleep 5 } function b { for i in {1..10}; do a $i & done wait } 2>/dev/null
Und wenn ich es laufen lasse:
$ b I'm background task 1 I'm background task 3 I'm background task 2 I'm background task 4 I'm background task 6 I'm background task 7 I'm background task 5 I'm background task 9 I'm background task 8 I'm background task 10
Und es gibt eine Verzögerung von 5 Sekunden, bevor ich meine Aufforderung zurück bekomme.
quelle
Die Subshell-Lösung funktioniert, aber ich wollte auch auf die Hintergrundjobs warten können (und am Ende nicht die Meldung "Fertig" haben).
$!
von einer Subshell ist in der aktuellen interaktiven Shell nicht "wartbar". Die einzige Lösung, die für mich funktioniert hat, war die Verwendung meiner eigenen Wartefunktion, die sehr einfach ist:myWait() { while true; do sleep 1; STOP=1 for p in $*; do ps -p $p >/dev/null && STOP=0 && break done ((STOP==1)) && return 0 done } i=0 ((i++)); p[$i]=$(do_whatever1 & echo $!) ((i++)); p[$i]=$(do_whatever2 & echo $!) .. myWait ${p[*]}
Leicht genug.
quelle