¿Por qué ejecutar un comando de shell de Linux con '&'?

30

Estoy usando Red Hat Linux Enterprise versión 5. He notado que a veces las personas ejecutan comandos con un par de &opciones. Por ejemplo, en el siguiente comando, hay dos &signos. ¿Cuál es el propósito de ellos? ¿Se usan siempre junto con nohup?

nohup foo.sh <script parameters> >& <log_file_name> &
George2
fuente

Respuestas:

15

Además de las respuestas de Martin, Ash y Kevin, a veces verás un ampersand utilizado matemáticamente para un bit a bit Y * :

$ echo $(( 11 & 7 ))
3

En caso de que no esté familiarizado con los operadores de bits:

11: 1011
 7: 0111
-------- AND
 3: 0011

En cada posición hay un bit en el primer número Y el segundo número, establezca ese bit en uno en la respuesta.

* La característica en la respuesta de Kevin se conoce como un AND lógico .

Para dar más detalles sobre la respuesta de Ash, cuando se usa en la redirección, el signo y puede decirle al shell que copie un descriptor de archivo. En este comando, echo "hello" > outputfile 2>&1el signo y comercial hace que cualquier salida que pueda ir al error estándar (stderr, descriptor de archivo 2) vaya al mismo lugar que la salida estándar (stdout, descriptor de archivo 1, el valor predeterminado para el lado izquierdo de >). El >& outputfileoperador es la abreviatura de > outputfile 2>&1.

Además, nuevo en Bash 4, hay dos nuevos terminadores para cláusulas en el casecomando ;&y ;;&que afectan si un caso "falla" y, de ser así, si se realiza la próxima prueba.

Pausado hasta nuevo aviso.
fuente
Genial, Dennis! Supongamos que uso el registro de terminal ssh en una máquina, luego uso el terminal ssh para ejecutar el comando (supongamos que es un proceso de larga duración), luego, si salgo de la sesión de terminal, el proceso de larga duración del comando finalizará correctamente. Y si quiero que el comando continúe ejecutándose incluso si salgo de shell, ¿debo usar nohup o & (al final del comando) o usar tanto nohup como &?
George2
1
@ George2: No, >& filenamegenera tanto stdout como stderr en el mismo archivo. Si solo quiere redirigir stderr (y dejar solo stdout), lo haría 2> filename. En cuanto a su otra pregunta, lo más probable es que use ambos nohupy &.
Pausado hasta nuevo aviso.
1
@ George2: si no ejecuta el comando en segundo plano, no recibirá un indicador de shell para que pueda emitir un logoutexit comando o .
Pausado hasta nuevo aviso.
2
George: Si no usa &, nunca volverá a recibir su mensaje para hacer otra cosa. El terminal se "colgará" hasta que el proceso (sea lo que sea) finalice o se termine / elimine. El & garantiza que el proceso se ejecute en segundo plano. Sin embargo, si cierra sesión, el sistema operativo finalizará todos sus procesos, lo que también mata su proceso en segundo plano. Si usa nohup, le está diciendo al proceso "ignore el comando que lo terminará".
Martin Marconcini
1
@ George2: Sí. "inmune a los bloqueos" == "proceso continuar" y "non-tty" == "salir de la sesión de la consola del terminal"
pausa hasta nuevo aviso
32

En un script de shell Bash, el signo "&" se usa para bifurcar procesos:

find -name hello &

Hará que el comando find se bifurque y se ejecute en segundo plano (siempre puede eliminarlo por su PID).

Martin Marconcini
fuente
Gracias Martin, supongamos que uso el registro de terminal ssh en una máquina, luego uso la terminal ssh para ejecutar el comando (supongamos un proceso de larga duración), luego, si salgo de la sesión de terminal, el proceso de larga duración del comando finalizará correctamente ? Y si ejecuto el comando usando & en el terminal ssh, incluso si salgo del terminal, el proceso a largo plazo del comando todavía se está ejecutando, ¿correcto?
George2
1
Eso es correcto George. Los procesos en segundo plano deben continuar hasta que salgan o los elimine. Sin embargo, como ya se ha señalado, no necesitará nada para evitar que el proceso muera cuando el usuario cierre la sesión.
Martin Marconcini
Gracias martin Quiero saber por qué necesitamos usar ambos & y nohup, y cuáles son sus funciones individuales que nos hacen alcanzar el objetivo de permitir que el comando continúe ejecutándose incluso si la consola del terminal se cierra. Leí la página de manual para nohup, y se menciona "ejecutar un comando inmune a los bloqueos, con salida a un no-tty", estoy confundido si lo inmune a los bloqueos es lo que quiere decir dejar que el comando continúe ejecutándose sin verse afectado por salir consola terminal? Si es así, creo que usar nohup es suficiente, y no es necesario usar &. ¿Algún comentario?
George2
1
Debe usar Ambos, si no usa &, el terminal no le permitirá ingresar ningún otro comando. La mejor manera de que lo veas es simplemente probarlo. Un buen ejemplo es un comando que lleva algo de tiempo, como un find: find -name SomeName /> somefile.txt intente con nohup y & y vea las diferencias.
Martin Marconcini
Esta tiene una gran respuesta para la pregunta de nohup: serverfault.com/questions/311593/…
joshperry
26

¿Por qué ejecutar un comando de shell de Linux con '&'?

Para recuperar su solicitud de inmediato y ejecutar el proceso en segundo plano.

¿Cuáles son las funciones de ellos?

nohup permite que el proceso en segundo plano continúe ejecutándose incluso después de que el usuario cierre sesión (o salga del shell de inicio).

> & redirige tanto la salida estándar como el error estándar al archivo de registro.

Y ejecuta todo en segundo plano, devolviéndole su solicitud de inmediato.

Explicación:

Cada proceso de Linux abre tres canales de E / S, una entrada "stdin", una salida estándar "stdout" y una salida de error estándar "stderr". Se pueden usar para binario, pero tradicionalmente son texto. Cuando la mayoría de los programas ven el cierre estándar, salen (el programador puede cambiarlo).

Cuando el shell padre sale, stdin se cierra en los hijos y (a menudo, generalmente) los hijos también salen. Además, los niños reciben una señal de software, SIGHUP, que indica que el usuario ha "colgado" (anteriormente, el módem) y el valor predeterminado aquí es salir también. (Tenga en cuenta que un programador puede cambiar todo esto al escribir el programa).

Entonces, lo que nohup hace es darle al proceso del niño un entorno de E / S separado, atando los entresijos a algo que no está atado al caparazón principal y protegiendo al niño de la señal SIGHUP. Una vez que el usuario se desconecta, verá el proceso de fondo nohup propiedad de init (proceso 1), no el shell del usuario.

Sin embargo nohup, no puede hacer el trabajo por completo si el proceso se ejecuta en primer plano, por lo que &se utiliza para ejecutar el programa en segundo plano, donde felizmente puede seguir ejecutándose con o sin un usuario conectado.

kmarsh
fuente
Supongamos que uso el registro de terminal ssh en una máquina, luego uso el terminal ssh para ejecutar el comando (supongamos que es un proceso de larga duración), luego, si salgo de la sesión de terminal, el proceso de larga duración del comando finalizará correctamente. Y si quiero que el comando continúe ejecutándose incluso si salgo de shell, ¿debo usar nohup o & (al final del comando) o usar tanto nohup como &?
George2
1
Correcto, use nohup y & para que el proceso continúe después de que SSH se desconecte.
kmarsh
Gracias kmarsh! Quiero saber por qué necesitamos usar ambos & y nohup, y cuáles son sus funciones individuales que nos hacen alcanzar el objetivo de permitir que el comando continúe ejecutándose incluso si la consola del terminal se cierra. Leí la página de manual para nohup, y se menciona "ejecutar un comando inmune a los bloqueos, con salida a un no-tty", estoy confundido si lo inmune a los bloqueos es lo que quiere decir dejar que el comando continúe ejecutándose sin verse afectado por salir consola terminal? Si es así, creo que usar nohup es suficiente, y no es necesario usar &. ¿Algún comentario?
George2
1
Editaré mi respuesta para responder.
kmarsh
13

Además de la respuesta de @ Martin: El otro uso de ampersand ( >&como arriba) es capturar ambos stdouty stderr. Normalmente, si redirige la salida a un archivo con solo '>', solo obtendrá la salida stdoutsin errores.

Ceniza
fuente
1. Gracias Ash, quiero confirmar con usted que "> & <nombre de archivo de registro>", volcará todo stderr y stdout en el archivo de registro, ¿correcto? 2. Y el uso de "> <nombre de archivo de registro>" volcará todas las stdout en el archivo de registro, ¿correcto?
George2
1
@George: Sí, eso es correcto.
Ash
Gracias Ash! Quiero saber por qué necesitamos usar ambos & y nohup, y cuáles son sus funciones individuales que nos hacen alcanzar el objetivo de permitir que el comando continúe ejecutándose incluso si la consola del terminal se cierra. Leí la página de manual para nohup, y se menciona "ejecutar un comando inmune a los bloqueos, con salida a un no-tty", estoy confundido si lo inmune a los bloqueos es lo que quiere decir dejar que el comando continúe ejecutándose sin verse afectado por salir consola terminal? Si es así, creo que usar nohup es suficiente, y no es necesario usar &. ¿Algún comentario?
George2
4

Además de la respuesta de Martin y Ash, a veces puedes ver el uso de una &&ficha. Esto se usa para decir "ejecutar el segundo comando si y solo si el primer comando se ejecutó correctamente". Un comando bien escrito, si tiene algún error, no saldrá con éxito.

[kevin@box ~]$ ls file && echo removing file && rm file
ls: file: No such file or directory
[kevin@box ~]$ touch file
[kevin@box ~]$ ls file && echo removing file && rm file
file
removing file
[kevin@box ~]$
Kevin M
fuente
Genial, Kevin! Supongamos que uso el registro de terminal ssh en una máquina, luego uso el terminal ssh para ejecutar el comando (supongamos que es un proceso de larga duración), luego, si salgo de la sesión de terminal, el proceso de larga duración del comando finalizará correctamente. Y si quiero que el comando continúe ejecutándose incluso si salgo de shell, ¿debo usar nohup o & (al final del comando) o usar tanto nohup como &?
George2
Cualquiera de los dos funcionaría. NOHUP fue la forma original de hacerlo, imagino (pero lo adivino por completo), pero el fondo funciona ahora. Una diferencia importante es cuando se ejecuta un shell interactivo al ingresar en un sistema remoto. El proceso NOHUP se ejecutaría en primer plano, pero seguiría ejecutándose si sale, mientras que el proceso en segundo plano volvería inmediatamente después de generar el comando. Pero cuando intenta salir de un shell interactivo con un comando ejecutándose en segundo plano, se le advierte primero.
Kevin M
2

La respuesta de Martin es buena, pero un poco ambigua. El comando siempre se bifurca y ejecuta, pero el comportamiento normal del shell es esperar en el comando hasta que salga. El ampersand lo pone en segundo plano para que recupere su terminal y pueda hacer otras cosas. Si el proceso arroja datos a stdout o stderr, esto se mezclará con lo que sea que esté haciendo en el indicador y puede confundirlo. Es por eso que redirige luego con> & /path/to/logfile.txt.

En respuesta a George2, el comportamiento normal para una salida de shell es enviar la señal SIGHUP a todos los procesos en el mismo grupo de procesos (esencialmente cosas que generó) y generalmente terminarán. Si desea que esto continúe incluso si cierra el proceso de shell, puede usar el comando nohup para hacer que ignoren esta señal y sigan ejecutándose. Hay un nombre especial para este tipo de proceso, se llama proceso demonio (pronunciado 'demonio').

Rich Homolka
fuente
Gracias rico! Supongamos que uso el registro de terminal ssh en una máquina, luego uso el terminal ssh para ejecutar el comando (supongamos que es un proceso de larga duración), luego, si salgo de la sesión de terminal, entonces el proceso de ejecución larga del comando finalizará correctamente. Y si quiero que el comando continúe ejecutándose incluso si salgo de shell, ¿debo usar nohup o & (al final del comando) o usar tanto nohup como &? ¿Y por qué?
George2
Hola George, lo siento, estoy respondiendo tan tarde. Sí, si sale del shell, el proceso a largo plazo finalizará. Si desea que continúe, debe hacer tanto nohup (para que no se termine cuando se cierra el shell) como & (para poner en segundo plano, para que pueda Crtl-D o salir de su shell). También puede mirar el comando setsid, que permitirá que su proceso se ejecute, haciendo que ignore SIGHUP de una manera ligeramente diferente.
Rich Homolka
Gran respuesta, explica las mejores prácticas para los procesos iniciados por shell en segundo plano.
Marcel Valdez Orozco