Tengo un script de shell script.sh
con un comando cmd
iniciado en segundo plano, es decir:
#!/bin/bash
…
cmd &
…
Si abro un emulador de terminal (he intentado xfce4-terminal y gnome-terminal) y ejecuto script.sh
dentro, mi comando cmd
se ejecuta efectivamente y se ejecuta en segundo plano, como se esperaba.
Pero, si abro un emulador de terminal del anterior (o al comienzo de mi sesión de escritorio, que es mi caso de uso real), y ejecuto mi script por
xfce4-terminal -H -x script.sh (or gnome-terminal -x script.sh)
el comando cmd
ya no se ejecuta.
Descubrí que puedo forzar que se ejecute al agregar set -m
mi script, pero no entiendo por qué es necesario (ni suficiente, en realidad) en este caso, y no en el anterior. De hecho, si pongo un set -o
en mi script, obtengo el mismo resultado en ambos casos.
¿Alguien puede explicarme esto y / o decirme la forma correcta de proceder con trabajos en segundo plano en scripts de shell? ¡Gracias!
EDITAR: En realidad, cmd
se ejecuta en ambos casos, pero en el segundo, se elimina inmediatamente por la terminación de script.sh
. Para evitar esto, uno puede usar nohup
, pero no es suficiente, y es lo más extraño para mí: uno también tiene que poner sleep 1
, o algo así, para permitir que el proceso se inicie correctamente en segundo plano y se disocie del shell principal, de lo contrario también se mata.
Realmente no entiendo esta diferencia de comportamiento entre los dos shells, ya que ambos no son interactivos, como se indicó en un comentario anterior.
cmd
que no se está ejecutando? ¿Se encuentra de manera fácil y única en la salida de ps (y dura lo suficiente como para encontrarlo), o hace un sonido u otra indicación de GUI?cmd
algo que se puede ver en un administrador de tareas, comosleep n
con lon
suficientemente grande. Pero uno puede elegir algo con una GUI, comofirefox
u otra cosa.Respuestas:
Si abre
xfce4-trminal
ognome-terminal
(u otro terminal) Su shell está en modo interactivo. Cada script se ejecuta en modo interactivo.Si corres
script.sh
poro
u otro terminal, su shell está en modo no interactivo.
Los scripts pueden verse obligados a ejecutarse en modo interactivo con la
-i
opción o con un#!/bin/bash -i
encabezado. Tenga en cuenta que esto puede causar un comportamiento errático de la secuencia de comandos o mostrar mensajes de error incluso cuando no haya ningún error.¿Qué es
set -m
? Es el modo monitor . Los procesos en segundo plano se ejecutan en un grupo de procesos separado y una línea que contiene su estado de salida se imprime al finalizar. Está habilitado de forma predeterminada para shells interactivos.¿Qué es
set -o
? Es escribir la configuración actual de las opciones en la salida estándar en un formato no especificado.¿Por qué
set -o
funciona?De todos modos,
set -m
es la forma preferida.fuente
set -o
mi script: en ambos casos, su salida es la misma, en particular con respecto al modo de monitor, que está desactivado (el valor predeterminado en modo no interactivo). No pongoset -o
a ver si funciona, sino a ver su salida.La pregunta ha sido respondida en Unix Stackexchange (ver también comentarios adicionales debajo de la respuesta). Se trata de quién envía la señal SIGHUP a quién y cuándo. Y una alternativa a
set -m / set +m
alrededorcmd &
descript.sh
estrap '' HUP / trap - HUP
.fuente