Funkcja powraca, ale blokowanie podstawiania poleceń, ponieważ utworzyłeś zadanie w tle, ale nadal masz otwarte standardowe wyjście fd. Po prostu zamknij, dodając >/dev/null
przed &
.
#!/bin/bash
function start {
leafpad >/dev/null &
echo $!
}
PID=$(start)
echo "PID is $PID"
Jeśli chcesz, aby Twój proces miał również stdin, stdout, stderr zamknięty, użyj tego:
leafpad >/dev/null 0>&1 2>&1 &
Spowoduje to zamknięcie stdin (0), stdout (1) i stderr (2), a następnie tła (&). Ponadto, gdy korzystasz z tych przekierowań strumienia , nie zapominaj, że są one „kopiowane”, co oznacza duplikowanie w kolejności wykonywania.
1>/dev/null 2>&1
i
2>&1 1>/dev/null
nie są takie same ! W pierwszym przypadku duplikujesz strumień do / dev / null (co jest tym, czego chcesz), w drugim przypadku kopiujesz / dev / stdout do stderr, a następnie zamykasz stdout. Tak więc każda wysłana wiadomość stderr
pojawi się w konsoli.
n>&-
gdzien
jest deskryptor pliku./dev/null
nie prowadzi do błędów we / wy, gdy proces próbuje zapisać swoje standardowe wyjście, ale stwierdza, że1
jest to nieprawidłowy FD. Więc terminologia w poście jest nieprawidłowa, a nie faktyczne programowanie bash. (W rzeczywistości powielenie FD 1 na 0 oznacza, że stdin będzie deskryptorem pliku otwieranymO_RDONLY
, co prawdopodobnie da błąd (zamiast pożądanego braku bajtów), gdy proces spróbuje odczytać.) Np.wc >/dev/null 0>&1
->wc: standard input: Bad file descriptor
exec <&- >&- <>/dev/null >&0
obsługuje stdin / out dość wyczerpująco. To robi różnicęzsh
przynajmniej w tym, co połączy automatycznie wszystkie otwarcia tego samego deskryptora, gdy ustawiony jest multios.