GNU/Linux >> Tutoriales Linux >  >> Linux

¿Alguien puede explicar en detalle qué hace set -m?

Citando la documentación de bash (de man bash ):

JOB CONTROL
       Job  control  refers to  the  ability  to selectively  stop
       (suspend) the execution of  processes and continue (resume)
       their execution at a later point.  A user typically employs
       this facility via an interactive interface supplied jointly
       by the operating system kernel's terminal driver and bash.

Entonces, dicho simplemente, tener set -m (el predeterminado para shells interactivos) permite usar funciones integradas como fg y bg ,que estaría deshabilitado bajo set +m (el valor predeterminado para shells no interactivos).

Sin embargo, no es obvio para mí cuál es la conexión entre el control del trabajo y la eliminación de los procesos en segundo plano al salir, pero puedo confirmar que hay una:ejecutar set -m; (sleep 10 ; touch control-on) & creará el archivo si uno sale del shell justo después de escribir ese comando, pero set +m; (sleep 10 ; touch control-off) & no lo hará.

Creo que la respuesta está en el resto de la documentación de set -m :

-m      Monitor  mode. [...]                     Background pro‐
        cesses run in a separate process group and a  line  con‐
        taining  their exit status is printed upon their comple‐
        tion.

Esto significa que los trabajos en segundo plano comenzaron en set +m no son "procesos en segundo plano" reales ("Los procesos en segundo plano son aquellos cuyo ID de grupo de procesos difiere del de la terminal"):comparten el mismo ID de grupo de procesos que el shell que los inició, en lugar de tener su propio grupo de procesos como los procesos en segundo plano adecuados. Esto explica el comportamiento observado cuando el shell se cierra antes de algunos de sus trabajos en segundo plano:si entiendo correctamente, al salir, se envía una señal a los procesos en el mismo grupo de procesos que el shell (así se eliminan los trabajos en segundo plano iniciados en set +m ), pero no a los de otros grupos de procesos (dejando así solos los verdaderos procesos en segundo plano iniciados bajo set -m ).

Entonces, en tu caso, el startup.sh presumiblemente, el script inicia un trabajo en segundo plano. Cuando este script se ejecuta de forma no interactiva, como a través de SSH como en la pregunta a la que se vinculó, el control del trabajo está deshabilitado, el trabajo "en segundo plano" comparte el grupo de procesos del shell remoto y, por lo tanto, se elimina tan pronto como sale del shell. Por el contrario, al habilitar el control de trabajos en ese shell, el trabajo en segundo plano adquiere su propio grupo de procesos y no se elimina cuando se cierra el shell principal.


Encontré esto en la lista de problemas de github, y creo que esto realmente responde a su pregunta.

No es realmente un problema de SSH, es más el comportamiento sutil en torno a los modos interactivos/no interactivos de BASH y la propagación de la señal a los grupos de procesos.

Lo siguiente se basa en https://stackoverflow.com/questions/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774and http:// www.itp.uzh.ch/~dpotter/howto/daemonize, con algunas suposiciones no completamente validadas, pero las pruebas sobre cómo funciona parecen confirmarlo.

pty/tty =falso

El shell bash lanzado se conecta a stdout/stderr/stdin del proceso iniciado y continúa ejecutándose hasta que no hay nada conectado a los sockets y sus hijos han salido. Un buen proceso demoníaco se asegurará de que no espere a que sus hijos salgan, bifurque un proceso hijo y luego salga. Cuando esté en este modo, SSH no enviará ningún SIGHUP al proceso secundario. Creo que esto funcionará correctamente para la mayoría de los scripts que ejecutan un proceso que maneja la demonización y no necesita estar en segundo plano. Cuando los scripts de inicio usan '&' para respaldar un proceso, entonces es probable que el principal problema sea si el proceso en segundo plano alguna vez intenta leer desde la entrada estándar, ya que eso activará un SIGHUP si la sesión finalizó.

pty/tty =verdadero*

Si el script de inicio pone en segundo plano el proceso iniciado, el BASHshell principal devolverá un código de salida a la conexión SSH, que a su vez buscará salir de inmediato, ya que no está esperando que finalice un proceso secundario y no está bloqueado en stdout/stderr/ entrada estándar Esto hará que se envíe un SIGHUP al grupo de procesos de shell de bash principal, que dado que el control de trabajos está deshabilitado en modo no interactivo en bash, incluirá los procesos secundarios que se acaban de iniciar. Cuando un proceso daemon inicia explícitamente una nueva sesión de proceso cuando se bifurca o en el proceso bifurcado, entonces él o sus hijos no recibirán el SIGHUP del proceso principal BASH que sale. Tenga en cuenta que esto es diferente de los trabajos suspendidos que verán un SIGTERM. Sospecho que los problemas en torno a este solo funcionamiento a veces tienen que ver con una ligera condición de carrera. Si observa el enfoque estándar para desamonizar -http://www.itp.uzh.ch/~dpotter/howto/daemonize, verá que en el código, la nueva sesión es creada por el proceso bifurcado que no puede ejecutarse antes del el padre sale, lo que da como resultado el comportamiento aleatorio de éxito/fracaso mencionado anteriormente. Una instrucción de suspensión dará suficiente tiempo para que el proceso bifurcado haya creado una nueva sesión, por lo que funciona en algunos casos.

pty/tty =true y el control de trabajos está explícitamente habilitado en bash

SSH no se conectará a stdout/stderr/stdin del shell bash ni a ningún proceso secundario iniciado, lo que significa que se cerrará tan pronto como el shell bash principal haya terminado de ejecutar los comandos solicitados. En este caso, con el control de tareas explícitamente habilitado, cualquier proceso iniciado por bash shell con '&' en segundo plano se colocará en una sesión separada inmediatamente y no recibirá la señal SIGHUP cuando el proceso principal de la sesión BASH salga (conexión SSH en este caso).

Qué se necesita para arreglar

Creo que las soluciones solo deben mencionarse explícitamente en la documentación de las operaciones run/sudo como un caso especial cuando se trabaja con procesos/servicios en segundo plano. Básicamente, use 'pty=false', o cuando eso no sea posible, habilite explícitamente el control de trabajo como el primer comando, y el comportamiento será correcto.

De https://github.com/fabric/fabric/issues/395


Linux
  1. ¿Qué pasa si 'matar -9' no funciona?

  2. ¿Qué significa &al final de un comando de Linux?

  3. ¿Qué significa set -e en un script bash?

  4. ¿Cómo puedo configurar la afinidad del procesador de un proceso en Linux?

  5. ¿Qué asesinos de procesos tiene Linux?

¿Qué indica esta estadística de proceso?

¿Qué hace Echo $? ¿¿Hacer??

¿Qué hace exactamente Grub_gfxpayload_linux=text?

¿Qué es la tabla de procesos de Linux? ¿En qué consiste?

¿Qué hace kill -- -0?

¿Qué hace 'set -e' y por qué podría considerarse peligroso?