Die Funktion kehrt zurück, aber die Befehlsersetzung wird blockiert, da Sie einen Hintergrundjob erstellt haben, Ihr stdout fd aber immer noch geöffnet ist. Schließen Sie es einfach durch Hinzufügen >/dev/null
vor dem &
.
#!/bin/bash
function start {
leafpad >/dev/null &
echo $!
}
PID=$(start)
echo "PID is $PID"
Wenn Ihr Prozess auch stdin, stdout, stderr closed haben soll, verwenden Sie Folgendes:
leafpad >/dev/null 0>&1 2>&1 &
Dadurch werden stdin (0), stdout (1) und stderr (2) und dann background (&) geschlossen. Wenn Sie diese Stream-Umleitungen verwenden, vergessen Sie nicht, dass sie "getäuscht" sind, dh in der Reihenfolge der Ausführung dupliziert.
1>/dev/null 2>&1
und
2>&1 1>/dev/null
sind nicht das Gleiche ! Im ersten Fall duplizieren Sie einen Stream nach / dev / null (was Sie wollen), im zweiten Fall duplizieren Sie / dev / stdout nach stderr und schließen dann stdout. Daher wird jede Nachricht, an die gesendet stderr
wird, in Ihrer Konsole angezeigt.
n>&-
Won
ist der Dateideskriptor?/dev/null
führt nicht zu E / A-Fehlern, wenn ein Prozess versucht, seine Standardausgabe zu schreiben, aber feststellt, dass dies1
eine ungültige FD ist. Die Terminologie im Beitrag ist also falsch, nicht die eigentliche Bash-Programmierung. (Tatsächlich bedeutet das Duplizieren von FD 1 auf 0, dass stdin ein Dateideskriptor ist, mitO_RDONLY
dem geöffnet wird , und der wahrscheinlich einen Fehler (statt der gewünschten Anzahl von verfügbaren Bytes) ausgibt, wenn der Prozess versucht zu lesen.) ZBwc >/dev/null 0>&1
->wc: standard input: Bad file descriptor
exec <&- >&- <>/dev/null >&0
geht ziemlich ausführlich mit stdin / out um. Es machtzsh
zumindest einen Unterschied, welche Art der Verkettung alle Öffnungen auf demselben Deskriptor automatisch ausführt, wenn Multios festgelegt werden.