¿Cómo puede un script bash detectar si se está ejecutando en segundo plano?
28
¿Hay alguna forma de que un script bash sepa si se está ejecutando en primer plano o en segundo plano, y para que pueda comportarse de manera ligeramente diferente en cada caso?
Here are the different values that the s, stat and state output
specifiers (header "STAT" or "S") will display to describe the state of
a process....+ is in the foreground process group
Para que pueda realizar una comprobación simple:
case $(ps -o stat=-p $$)in*+*) echo "Running in foreground";;*) echo "Running in background";;esac
¿Seguramente todo lo invocado dentro de $ (...) se está ejecutando en segundo plano ...? Sin embargo, supongo que el grupo de procesos es lo importante, no puedo negar que funciona.
Ed Randall
2
Mire el archivo /etc/bash.bashrc ".
La línea que tiene "$ PS1". Luego haz un "man bash" y busca el token PS1.
Todas las soluciones anteriores implican procesos de desove, etc. Muy, muy feo, ya que .bashrcse llama cada vez que se inicia un bash shell, por lo tanto, esas soluciones terminan lanzando miles de procesos.
Mucho más limpio es preguntar bash en sí: bash tiene una variable predefinida $-que tiene "i" si se ejecuta en un shell interactivo. Por ejemplo, poner esto en su .bashrc es mucho más limpio y mucho más barato y, lo más importante, ¡siempre funcionará!
¿PORQUE ESTAS GRITANDO? Eso se ve muy, muy feo ...
Pierre.Vriens
Solución simple y correcta.
Ed Randall
0
Si bien podría pensar que verificar si el shell se ejecuta en modo interactivo dará el mismo resultado, en la práctica, esto no lo es. El concepto se ve similar pero en realidad es diferente. Puede ejecutar un script interactivo en la entrada de alimentación en segundo plano gracias a esperar . Además, puede iniciar su script con bash con el -largumento. Por lo tanto, no podemos confiar en la interactividad bash para verificar si nuestro script se ejecuta en segundo plano o en primer plano.
En el código anterior, estamos generando el resultado en un archivo de texto porque stdoutno está conectado cuando un proceso se ejecuta en segundo plano.
Respuestas:
Citando
man ps
:CÓDIGOS ESTATALES DE PROCESO
Para que pueda realizar una comprobación simple:
fuente
Mire el archivo /etc/bash.bashrc ".
La línea que tiene "$ PS1". Luego haz un "man bash" y busca el token PS1.
sale de un script que no es interactivo.
fuente
Todas las soluciones anteriores implican procesos de desove, etc. Muy, muy feo, ya que
.bashrc
se llama cada vez que se inicia un bash shell, por lo tanto, esas soluciones terminan lanzando miles de procesos.Mucho más limpio es preguntar bash en sí: bash tiene una variable predefinida
$-
que tiene "i" si se ejecuta en un shell interactivo. Por ejemplo, poner esto en su .bashrc es mucho más limpio y mucho más barato y, lo más importante, ¡siempre funcionará!fuente
Si bien podría pensar que verificar si el shell se ejecuta en modo interactivo dará el mismo resultado, en la práctica, esto no lo es. El concepto se ve similar pero en realidad es diferente. Puede ejecutar un script interactivo en la entrada de alimentación en segundo plano gracias a esperar . Además, puede iniciar su script con bash con el
-l
argumento. Por lo tanto, no podemos confiar en la interactividad bash para verificar si nuestro script se ejecuta en segundo plano o en primer plano.La respuesta de devnull es, por lo tanto, correcta . Para determinar si el proceso se está ejecutando en primer plano, la utilidad ps comprueba si el grupo de proceso (pgrp) es el mismo que el ID del grupo de proceso asociado con el terminal de control de la sesión (tpgid) y agrega un
+
signo en la salida de acuerdo con el proceso estado.Sabiendo eso, definitivamente podemos tener una versión pura de bash de la prueba:
En el código anterior, estamos generando el resultado en un archivo de texto porque
stdout
no está conectado cuando un proceso se ejecuta en segundo plano.Tenga en cuenta los días 4 y los elementos 8 de la tabla corresponden respectivamente a
pgrp
ytpgid
( ver el proc / [pid] / / stat sección de la página hombre -man 5 proc
).fuente