¿Cómo ejecuto múltiples comandos de fondo en bash en una sola línea?

169

Normalmente ejecuto múltiples comandos con algo como esto:

sleep 2 && sleep 3

o

sleep 2 ; sleep 3

pero ¿qué pasa si quiero ejecutarlos en segundo plano desde un comando de línea de comando?

sleep 2 & && sleep 3 &

no funciona Y tampoco lo hace reemplazar &&con;

¿Hay una manera de hacerlo?

Palacio Chan
fuente
8
Use ()para rodear el comando.
nhahtdh
1
unix.stackexchange.com/questions/67006/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

319

¿Exactamente cómo quieres que corran? Si desea que se inicien en segundo plano y se ejecuten secuencialmente , haría algo como esto:

(sleep 2; sleep 3) &

Si, por otro lado, desea que se ejecuten en paralelo en segundo plano, puede hacer esto:

sleep 2 & sleep 3 &

Y las dos técnicas podrían combinarse, tales como:

(sleep 2; echo first finished) & (sleep 3; echo second finished) &

Bash es bash, a menudo hay una multitud de técnicas diferentes para realizar la misma tarea, aunque a veces con sutiles diferencias entre ellas.

Kitsune
fuente
20
Esta es una respuesta concisa y bien pensada que "le enseña a un hombre a pescar" de por vida. Gracias.
Ambrus
2
¿Qué pasa si lo hacemos sleep 2 && sleep 3 &? Lo intenté en bash y parece funcionar de la misma manera (lo intenté con echo).
Wajahat
@HakanBaba, sí, de hecho crea una subshell en segundo plano.
Douwe van der Leest
3
@Wajahat, ¿lo intentaste sleep 2 && echo "foo" && sleep 3 & echo "bar""? El &&operador le dice al shell que ejecute el comando antes que él, y solo si ese comando se ejecuta sin ningún error, el shell ejecuta el comando posterior. Esto es esencialmente diferente de ;, porque ;permite que el comando posterior se ejecute independientemente del estado de salida del comando anterior a menos que haya sido un error fatal. El &le dice al shell que ejecute todos los comandos "conectados" que lo preceden, en segundo plano. "conectado" aquí significa que el comando es parte de una tubería ( |) o un operador lógico.
Douwe van der Leest
Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence.en manual bash.
Jinbeom Hong
49

Debes agregar algunos parens en tu última versión:

(sleep 2 &) && (sleep 3 &)

o esto también funciona

(sleep 2 &) ; (sleep 3 &)
iagreen
fuente
Nota: Cuando se usa una lista con &, su estado de salida siempre es cero. Entonces, los dos casos anteriores hacen lo mismo (el shell ejecuta ambos lados a su vez de forma asincrónica ).
Jinbeom Hong
9

para ejecutar múltiples comandos de fondo, debe agregar el &final de cada comando. ex: (command1 &) && (command2 &) && (command3 &)

Saeed
fuente
5

Las respuestas anteriores usan paréntesis. Bash también puede usar llaves para un propósito similar:

{ sleep 2 && sleep 3; } &

Tenga en cuenta que los corchetes son más exigentes con la sintaxis: se requieren el espacio después {, el espacio antes }y el punto y coma final. En algunas situaciones, las llaves son más eficientes porque no bifurcan una nueva subshell. En este caso, no sé si hace la diferencia.

Greg Reagle
fuente
1
¿Qué hay de { sleep 2; sleep 3; } &?
Kenny Evitt
4

Esto funciona:

$(sleep 2 &) && sleep 3 &

También puedes hacer:

$(sleep 2 && sleep 3) &
higuaro
fuente
0

Yo tengo la misma misión también. Lo he intentado (sleep2 ; fg )& sleep3 ; fg, está funcionando. Y cuando preasiona ctrl + c duplicado, los dos procesos pueden detenerse.

dingyang wang
fuente
0

Puede usar la sustitución del comando bash de $(command)esta manera:

$(command1 ; command2) &

Tenga en cuenta que stdin y stdout todavía están vinculados al proceso padre y redirigir al menos el stdout puede ser complicado. Alternativamente, puede encadenar los comandos en una sola línea y luego pasar la cadena al bashcomando para generar un nuevo proceso que se encargará de la ejecución.

bash -c "command1 ; command2" & 

Esto es especialmente útil en un script bash cuando necesita ejecutar múltiples comandos en segundo plano.

Estas dos declaraciones deben ser equivalentes. Se genera un proceso bash en ambos casos para manejar el comando (cadena de comandos) y &al final se separa la ejecución.

Esta vez puede agregar &>/dev/nullantes del &final del comando para redirigir al menos la salida estándar y evitar la salida en la salida estándar del proceso principal. Algo como:

bash -c "command1 ; command2" &>/dev/null &
Bemipefe
fuente
-1

Si desea ejecutar varios comandos secuencialmente , hay un método realmente simple que funciona en todas partes: ¡Crear un archivo! El beneficio de este método es que es limpio y simple.

Primero, cree su archivo con un nombre, por ejemplo commands.sh. Luego, pon tus comandos allí. Aquí hay una muestra:

commands.sh:

#!/system/bin/sh

sleep 3;
sleep 2;

Bien, ahora estamos en el último paso. Para ejecutar comandos en segundo plano (secuencialmente), simplemente ejecute:

$ sh commands.sh &
MAChitgarha
fuente