/ / Stille Hintergrundjobs in zsh - zsh

Stille Hintergrundjobs in zsh - zsh

ich renne Archey in meinem .zshrc. Das Problem ist, dass aufgrund der Anzeige der aktuellen IP manchmal zwei Sekunden vergehen. Um dies weniger auff├Ąllig zu machen, habe ich es folgenderma├čen in den Hintergrund gestellt:

# .zshrc
archey &
# lots of foo
wait

Auf diese Weise kann es die IP abrufen, w├Ąhrend viele andere Dinge in meinem zshrc erledigt werden. Aber jetzt zeigt zsh die Job- und Prozess-ID an, und diese Pr├╝fung ist jedes Mal beendet:

Last login: Mon Jul 10 11:12:07 on ttys002
[1] 40436

# archey output

[1]  + done       archey

~
ÔŁ»

Da das Dokument angibt, dass es an stderr gesendet wird, habe ich erfolglos versucht, 2> / dev / null zu verwenden.

Wie kann ich diese beiden Zeilen entfernen?

Antworten:

4 f├╝r Antwort Ôäľ 1

Zsh bietet die MONITOR und NOTIFY Sie k├Ânnen sie deaktivieren, um den Statusbericht von Hintergrundjobs stumm zu schalten.

() {
setopt LOCAL_OPTIONS NO_NOTIFY NO_MONITOR
archey &
# ...
wait
}

1 f├╝r Antwort Ôäľ 2

Diese beiden Zeilen werden an ausgegeben stderr der Schale, nicht des Prozesses. Sie k├Ânnen sie nicht aus zsh verschwinden lassen.

Wenn Sie den Kommentaren entnehmen, dass die Ausgabe angezeigt werden soll, m├╝ssen Sie drei Schritte ausf├╝hren:

  1. Um zu vermeiden, dass Archey im Hintergrund gestartet wird, m├╝ssen Sie es von einem Skript aus starten
  2. Um die Ergebnisse von archey zur├╝ck an das Hauptskript zu ├╝bermitteln, m├╝ssen Sie ein tempfile oder ├Ąhnliches verwenden
  3. Um zu verstehen, wenn es fertig ist, k├Ânnen Sie nicht verwenden wait da kommt es auf den lauten hintergrundstart an

wrap-archey.sh:

#/bin/sh
archey >"$1" 2>&1
rm "$2"

start-archey.sh:

/path/to/wrap-archey.sh "$1" "$2" >/dev/null 2>&1 &

.zshrc:

ARCHEYOUT=$(mktemp)
ARCHEYFLAG=$(mktemp)
/path/to/start-archey.sh "$ARCHEYOUT" "$ARCHEYFLAG" >/dev/null 2>&1
#
# lots of foo
#
while test -f "$ARCHEYFLAG"; do sleep 0.1 ; done
cat "$ARCHEYOUT"
rm "$ARCHEYOUT"

wrap-archey.sh leitet die Ausgabe in ein tempfile um und entfernt anschlie├čend ein Flagfile. Dies wird f├╝r die R├╝ckkommunikation ben├Âtigt.

start-archey.sh startet wrap-archey.sh im Hintergrund, eliminiert das Rauschen im Hauptskript und kehrt sofort zur├╝ck.

.zshrc richtet flagfile und resultfile ein, f├╝hrt start-archey.sh unbeaufsichtigt im Hintergrund aus, f├╝hrt dann foo aus und wartet, bis archey abgeschlossen ist, indem die flagfile abgefragt wird. Dann r├Ąumt es auf.


1 f├╝r Antwort Ôäľ 3

Wenn Sie keine Subshell verwenden m├Âchten, k├Ânnen Sie Folgendes verwenden:

# Run the command given by "$@" in the background
silent_background() {
if [[ -n $ZSH_VERSION ]]; then  # zsh:  https://superuser.com/a/1285272/365890
setopt local_options no_notify no_monitor
# We"d use &| to background and disown, but incompatible with bash, so:
"$@" &
elif [[ -n $BASH_VERSION ]]; then  # bash: https://stackoverflow.com/a/27340076/5353461
{ 2>&3 "$@"& } 3>&2 2>/dev/null
else  # Unknownness - just background it
"$@" &
fi
disown &>/dev/null  # Close STD{OUT,ERR} to prevent whine if job has already completed
}

Dann:

silent_background archey #  Or whatever command you want to background

0 f├╝r Antwort Ôäľ 4

Dies sollte ohne zus├Ątzliche Skriptdateien funktionieren:

tmpf=`mktemp`
{ archey ; echo 1 > "$tmpf" ; } &|

# foo

while [ ! -s "$tmpf" ] ; do sleep 0.1 ; done
rm "$tmpf"
unset tmpf

Der Schl├╝ssel ist &| Operator. Der angegebene Befehl wird im Hintergrund ausgef├╝hrt, aber der Befehl ist kein Job, sodass Ihre Anzeige keinen Spam enth├Ąlt. Sie k├Ânnen nicht verwenden wait obwohl. Ich habe eine tempor├Ąre Datei verwendet, um festzustellen, ob archey hat beendet.

Wenn dein # foo erzeugt auch Ausgabe, k├Ânnen Sie eine Race-Bedingung auftreten. In diesem Fall ist es sinnvoll zu erfassen archey Ausgabe in eine andere tempor├Ąre Datei (wie in dieser anderen Antwort) und drucke es am Ende aus.

Ich empfehle nicht, eine einzelne tempor├Ąre Datei f├╝r zu verwenden archey Ausgang und als Trigger. Wenn Sie das dann tun while test kann true zur├╝ckgeben, wenn archey schreibt noch in die datei, denke ich.