Ejecutar un proceso en segundo plano en bash es bastante fácil.
$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+ Done echo "Hello I'm a background task"
Sin embargo, el resultado es detallado. En la primera línea se imprime la identificación del trabajo y la identificación del proceso de la tarea en segundo plano, luego tenemos la salida del comando, finalmente tenemos la identificación del trabajo, su estado y el comando que activó el trabajo.
¿Hay alguna forma de suprimir el resultado de ejecutar una tarea en segundo plano de modo que el resultado se vea exactamente como lo haría sin el signo comercial al final? Es decir:
$ echo "Hello I'm a background task" &
Hello I'm a background task
La razón por la que pregunto es que quiero ejecutar un proceso en segundo plano como parte de un comando de finalización de tabulación, por lo que la salida de ese comando debe ser ininterrumpida para que tenga sentido.
fuente
Respuestas:
No relacionado con la finalización, pero puede suprimir esa salida poniendo la llamada en una subcapa:
(echo "Hello I'm a background task" &)
fuente
wait
que finalice el trabajo en segundo plano.Partiendo de la respuesta de @ shellter, esto funcionó para mí:
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:~$
No conozco el razonamiento detrás de esto, pero recordé de una publicación anterior que el rechazo evita que bash genere los ID del proceso.
fuente
;
al final. (sin dormir) . 2. PERO noté que cuando agreguéecho STDERR 2>&1
en la línea "siguiente",[1]+ Done ...
¡apareció la cosa! . 3. Mi solución (como ya he señalado) funcionaksh
yecho STDERR 2>&1
solo produce la salida STDERR. Bueno, vive y aprende para los dos. Buena suerte a todos.En algunas versiones más nuevas de bash y en ksh93, puede rodearlo con un sub-shell o grupo de procesos (es decir
{ ... }
)./home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null Hello I'm a background task /home/shellter $
fuente
ksh93+
usándolo como mi shell principal. Este código funciona según lo prometido en ksh. pero como el OP está etiquetado conbash
, entiendo su dv. Vea los resultados de la prueba bash en la respuesta de @ Tyzoid. ¡Buena suerte a todos!wait $!
lo que no parece ser el caso de la respuesta aceptada.Sobre la base de la respuesta anterior, si necesita permitir que stderr llegue desde el comando:
f() { echo "Hello I'm a background task" >&2; } { f 2>&3 &} 3>&2 2>/dev/null
fuente
disown
en algunas circunstancias .Basado en esta respuesta , se me ocurrió la más concisa y correcta:
silent_background() { { 2>&3 "$@"& } 3>&2 2>/dev/null disown &>/dev/null # Prevent whine if job has already completed } silent_background date
fuente
Tratar:
user@host:~$ read < <( echo "Hello I'm a background task" & echo $! ) user@host:~$ echo $REPLY 28677
Y ha ocultado tanto la salida como el PID . Tenga en cuenta que aún puede recuperar el PID de $ REPLY
fuente
Perdón por la respuesta a una publicación anterior, pero creo que esto es útil para otros y es la primera respuesta en Google.
Tenía un problema con este método (subcapas) y usaba 'esperar'. Sin embargo, como lo estaba ejecutando dentro de una función, pude hacer esto:
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
Y cuando lo ejecuto:
$ 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
Y hay un retraso de 5 segundos antes de que recupere mi mensaje.
fuente
La solución de subshell funciona, pero también quería poder esperar en los trabajos en segundo plano (y no tener el mensaje "Listo" al final).
$!
de un subshell no es "waitable" en el shell interactivo actual. La única solución que funcionó para mí fue usar mi propia función de espera, que es muy simple: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[*]}
Suficientemente fácil.
fuente