Uruchamianie procesu w tle w bash jest dość łatwe.
$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+ Done echo "Hello I'm a background task"
Jednak dane wyjściowe są szczegółowe. W pierwszym wierszu wypisywany jest identyfikator zadania i identyfikator procesu zadania w tle, następnie mamy wyjście polecenia, na końcu mamy identyfikator zadania, jego status i polecenie, które wyzwoliło zadanie.
Czy istnieje sposób na pominięcie wyniku działania zadania w tle w taki sposób, aby dane wyjściowe wyglądały dokładnie tak, jak bez znaku ampersand na końcu? To znaczy:
$ echo "Hello I'm a background task" &
Hello I'm a background task
Powodem, o który pytam, jest to, że chcę uruchomić proces w tle jako część polecenia uzupełniania tabulacji, więc wyjście tego polecenia musi być nieprzerwane, aby miało jakikolwiek sens.
bash
bash-completion
Alex Spurling
źródło
źródło
Odpowiedzi:
Nie ma związku z dokończeniem, ale możesz ukryć to wyjście, umieszczając wywołanie w podpowłoce:
(echo "Hello I'm a background task" &)
źródło
wait
praca w tle zakończyła się.Opierając się na odpowiedzi @ shellter, zadziałało to dla mnie:
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:~$
Nie znam powodu tego, ale przypomniałem sobie ze starego postu, w którym wyparcie się uniemożliwia bashowi wyprowadzanie identyfikatorów procesów.
źródło
;
na końcu. (bez snu) . 2. ALE zauważyłem, że kiedy dodałemecho STDERR 2>&1
w "następnej" linii, to się[1]+ Done ...
pojawiło! . 3. Moje rozwiązanie (jak już zauważyłem) działa wksh
iecho STDERR 2>&1
generuje tylko wyjściowy STDERR. Cóż, żyj i ucz się dla nas obu. Powodzenia wszystkim.W niektórych nowszych wersjach basha i ksh93 można otoczyć go podpowłoką lub grupą procesów (np
{ ... }
.)./home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null Hello I'm a background task /home/shellter $
źródło
ksh93+
jako mojej podstawowej powłoki. Ten kod działa zgodnie z obietnicą w ksh. ale ponieważ OP jest oznaczony tagiembash
, rozumiem twój dv. Zobacz wyniki testów bash w odpowiedzi @ Tyzoid. Powodzenia wszystkim!wait $!
którym nie wydaje się, aby tak było w przypadku zaakceptowanej odpowiedzi.Opierając się na powyższej odpowiedzi, jeśli chcesz zezwolić na przechodzenie stderr z polecenia:
f() { echo "Hello I'm a background task" >&2; } { f 2>&3 &} 3>&2 2>/dev/null
źródło
disown
w niektórych okolicznościach będziesz potrzebować .Na podstawie tej odpowiedzi wymyśliłem bardziej zwięzłe i poprawne:
silent_background() { { 2>&3 "$@"& } 3>&2 2>/dev/null disown &>/dev/null # Prevent whine if job has already completed } silent_background date
źródło
Próbować:
user@host:~$ read < <( echo "Hello I'm a background task" & echo $! ) user@host:~$ echo $REPLY 28677
I ukryłeś zarówno wyjście, jak i PID . Zauważ, że nadal możesz pobrać PID z $ REPLY
źródło
Przepraszam za odpowiedź na stary post, ale myślę, że jest to przydatne dla innych i jest to pierwsza odpowiedź w Google.
Miałem problem z tą metodą (podpowłoki) i użyłem „czekaj”. Jednak ponieważ uruchamiałem go w funkcji, mogłem to zrobić:
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
A kiedy to uruchomię:
$ 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
I zanim otrzymam zwrotny monit, upływa 5 sekund.
źródło
Rozwiązanie podpowłoki działa, ale chciałem również móc czekać na zadania w tle (i nie mieć na końcu komunikatu „Gotowe”).
$!
z podpowłoki nie „czeka” w bieżącej powłoce interaktywnej. Jedynym rozwiązaniem, które zadziałało, było użycie własnej funkcji czekania, która jest bardzo prosta: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[*]}
Wystarczająco łatwe.
źródło