¿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?


8
Use ()para rodear el comando.
nhahtdh

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.


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 &)

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 &)


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.


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) &

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.


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 &

-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 &
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.