¿Cuál es el significado de & al final de un comando?

12

Tengo una línea de script de inicio:

pyprogramm >> /dev/null  2>&1 &

Significados:

>> /dev/null - redirect stdout to null device
2>&1 - redirect stderr to stdout (that is redirected to null device)

¿Pero qué significa el último &?

vico
fuente

Respuestas:

16

¿Qué es el & terminator?

El &operador final al final de un comando se usa para poner comandos en segundo plano. Esta es realmente una sintaxis estándar especificada por el estándar POSIX :

Listas asincrónicas

Si el operador de control ('&') termina un comando, el shell ejecutará el comando de forma asíncrona en un subshell. Esto significa que el shell no deberá esperar a que termine el comando antes de ejecutar el siguiente comando.

El formato para ejecutar un comando en segundo plano es:

comando1 y [comando2 y ...]

El propósito de los comandos en segundo plano es ejecutar un comando sin el shell principal en el script o el shell interactivo esperando el comando, lo que bloquearía la ejecución de otros comandos y crearía un inconveniente para que el usuario espere. Esto es útil para iniciar comandos de ejecución prolongada, pero debe continuar trabajando en el shell actual. Como puede adivinar, esto se originó en el momento en que no había emuladores de terminal de múltiples pestañas, pero los terminales eran hardware físico real conectado a una computadora.

De la definición se puede ver que &también sirve como terminador de comandos para listas de comandos, al igual que lo ;hace. En su ejemplo específico, pyprogramm >> /dev/null 2>&1 &solo hay un comando en la lista.

Secuencial; listas vs asincrónicas y listas

Más generalmente,

echo Hello ; echo World ;

y

echo Hello & echo World &

son dos ejemplos de listas terminadas por los operadores ;y &. Una diferencia es que la &lista terminada tendrá una entrada conectada /dev/nullsi el control de trabajo está deshabilitado:

Si el control de trabajo está deshabilitado (vea set, -m), la entrada estándar para una lista asincrónica, antes de que se realice cualquier redirección explícita, se considerará asignada a un archivo que tenga las mismas propiedades que / dev / null. Esto no sucederá si el control de trabajo está habilitado. En todos los casos, la redirección explícita de la entrada estándar anulará esta actividad.

Sin embargo, en la lista secuencial, cada comando aún se ha stdinconectado al terminal si no hay redireccionamientos explícitos.

Tenga en cuenta también que, desde la definición que mencionamos anteriormente, &ejecuta comandos en subshell. Por el contrario, la ;lista terminada se ejecuta en el shell actual. También hay diferencia en los estados de salida. Para &el estándar dice:

El estado de salida de una lista asincrónica será cero.

Esto es importante cuando desea poner múltiples comandos en segundo plano. Cuando escriba un script o comando, tendrá que elegir comandos para los que no le importa si fallaron o no, o tendrá que encontrar una manera de manejar el estado de salida distinto de cero (error). En su ejemplo específico, la pyprogramm >> /dev/null 2>&1 &ejecución en segundo plano debería tener alguna forma de indicar si falló o no, sin embargo, al juzgar que usa 2>&1está ocultando la salida de error al redirigir, y probablemente asuma que el script no debería fallar.

Por el contrario, el ;estado de salida se define como:

El estado de salida de una lista secuencial será el estado de salida del último comando en la lista.

Una vez más, esto tiene implicaciones sobre cómo escribir una lista secuencial de comandos en la línea de comandos y cómo desea que se manejen las cosas si algunos de los comandos de la lista fallaron.


Notas al margen y lecturas adicionales

  • El hecho de que este es POSIX medios de definición que todos Bourne-como conchas, significado bash, dashy kshdebe ser compatible con él.

  • &en la redirección es diferente de &como terminador de comando. Significa duplicar (copiar) el objeto descriptor de archivo. Consulte ¿Qué significa y significa exactamente en la redirección de salida?

  • También bashhay un |&operador (nota que no hay espacio entre la tubería y el ampersand). Del manual bash :

    Si se utiliza | &, el error estándar del comando, además de su salida estándar, se conecta a la entrada estándar del comando 2 a través de la tubería; es la abreviatura de 2> y 1 |. Esta redirección implícita del error estándar a la salida estándar se realiza después de cualquier redirección especificada por el comando.

Sergiy Kolodyazhnyy
fuente
2
Lo que dices sobre &ocultar la salida no suena correcto. El párrafo del estándar que está citando habla de entrada , no de salida . La razón para la distinción entre habilitar o no el control del trabajo es que se suspenderá un proceso en segundo plano que intente leer desde el tty. En ese punto, debe usar el control de trabajo para ponerlo en primer plano y proporcionar la entrada que está esperando. Todo eso no se puede hacer sin el control del trabajo y, por lo tanto, si el control del trabajo está deshabilitado, el stdin debe ser redirigido /dev/nullo equivalente.
Kasperd
También vi un error en tu edición. En un lugar donde escribió habilitado donde debería haber escrito deshabilitado.
Kasperd
@kasperd Sí, estaba volviendo a leer la página POSIX cuando me di cuenta de eso también. Ya está arreglado. Avíseme si algo más necesita edición. Gracias :)
Sergiy Kolodyazhnyy
3

Significa ejecutar el comando en segundo plano. El script de llamada continúa en lugar de bloquearse hasta que se completa el comando llamado.

Robert Longson
fuente
0

&Esto devuelve el control de la secuencia de comandos al sistema operativo, pero envía la respuesta al fondo, no nohupporque envía directamente la ejecución completa

Bryro
fuente