Procesos en segundo plano sin "&"

24

Digamos que inició una nueva aplicación en Linux (como un editor de texto, etc.), pero olvidó usar el "&". ¿Qué comando (s) usaría para hacer que ese proceso se ejecute en segundo plano, sin tener que CERRAR esa aplicación? De esta manera, puede hacer que ambos procesos se abran y funcionen por separado (por ejemplo, el terminal de línea de comando que utilizó para crear el proceso y el proceso, como un editor de texto que aún se ejecuta.

D0uble7
fuente
Técnicamente no, pero tal vez tmuxofrece la misma funcionalidad deseada en su pregunta.
mkc
1
No pase por alto la alternativa simple de abrir otro shell cuando sea posible.
jpmc26

Respuestas:

43

En la ventana de terminal, normalmente escribirías Control+ Zpara "suspender" el proceso y luego usarías el bgcomando para "ponerlo en segundo plano".

por ejemplo, con un comando de suspensión

$ /bin/sleep 1000
^Z[1] + Stopped                  /bin/sleep 1000
$ bg
[1]     /bin/sleep 1000&
$ jobs
[1] +  Running                 /bin/sleep 1000
$ 

Podemos ver que el proceso se está ejecutando y todavía tengo mi línea de comando.

Stephen Harris
fuente
55
Puede ser interesante agregar que el proceso puede volver a primer plano con el fgcomando, que toma la identificación del trabajo (especificada entre paréntesis, 1en este caso) como parámetro. No es específico para el uso bgy se puede hacer en procesos iniciados con &.
Aaron
14

Ctrl+ Zes la forma de hacerlo, pero solo para completar: la pregunta pide "comando", y eso sería (desde otro terminal):

kill -STOP pid_of_the_running_applications

y luego por supuesto

bg

desde el terminal de aplicaciones.

Radovan Garabík
fuente
66
kil-STOP y luego kill -CONT
Michel Billaud
10

En Bash:

Ctrl+ Zy luego bg.

Ahora corre jobsy mira el resultado.

Tomász
fuente
2
@grooveplex Tomas respondió primero, por lo que sería más apropiado comentar debajo de la respuesta de Stephen, que la suya es básicamente la respuesta de tomas con más detalles.
Anthon el
2
En realidad respondimos al mismo tiempo. No es sorprendente que ambos dijimos lo mismo, ya que es la respuesta obvia :-) Ninguno de los dos copió al otro. Mi respuesta llegó poco después de la de Thomas porque había dedicado el tiempo extra a crear y formatear el ejemplo.
Stephen Harris el
1
Y el mío dice que está en Bash, así que no son lo mismo.
Tomasz
1
Je, hay un punto potencial allí. Requiere que el shell tenga control de trabajo. Algunas de las primeras máquinas en las que trabajé (basadas en SVr2) no tenían eso, /bin/shasí que esto no habría funcionado :-)
Stephen Harris
1

Como medida preventiva por la inconveniencia de tener que pulse CTRL- z, usted podría hacer un script de envoltorio para su editor para que ejecute su editor en el fondo. De esta manera, no necesitaría tener cuidado de recordar iniciarlo en segundo plano explícitamente:

    #!/bin/sh

    EDITOR="emacs" # or whatever

    if [ -z "${DISPLAY}" ]; then
      ${EDITOR} "$@"
    else
      ${EDITOR} "$@" &
    fi

Arriba, primero tratamos de determinar si tiene un servidor X disponible y solo luego ejecuta el editor en segundo plano (si no, muchos editores de Unix usarán su terminal y no desea ejecutar el editor como un proceso en segundo plano en este caso) . Pasará todos los argumentos a su editor de elección literal ( "$@") tal como lo proporcionó para el script de envoltura.

En cuanto al comando que se está perdiendo ... Según mi experimentación básica, para los programas GUI que no involucran terminal, podría ser tan simple como enviar primero SIGSTOPy luego SIGCONTal proceso de primer plano (usando el killcomando si usa un script de shell para implementar esto) . Por supuesto, necesitaría ejecutarlo en otra ventana / pestaña de terminal, y la dificultad sería encontrar de manera conveniente y genérica el PID al que desea enviar su señal. Por defecto, puede enviar las dos señales a todos los procesos del nombre dado (por defecto a su editor favorito y permitiendo también usar PID como argumentos):

    #!/bin/sh

    EDITOR=emacs # whatever

    stop_cont_prog()
    {
      case "$1" in
        # begin with number is considered PID - this is not good 
        # enough to be taken seriously...
        [1-9]*) kill -SIGSTOP "$1"; kill -SIGCONT "$2";;
        *)      killall -SIGSTOP "$1"; killall -SIGCONT "$2";;
      esac
    }

    if [ -n "$1" ]; then
      for prog in "$@"; do stop_cont_prog "$1"; done
    else  
      stop_cont_prog "${EDITOR}"
    fi

Este método me dio correctamente mis pestañas de terminal después de ejecutar (varios) emacscomandos en segundo plano. Pero el proceso de emacs que se ejecuta en el terminal no se restauró correctamente debido al control del trabajo de shell o la confusión de la configuración del terminal. Entonces, este método se beneficiaría de cierta sofisticación.

Esto SIGSTOPes exactamente lo que se envía al proceso de primer plano cuando presiona (por defecto común) CTRL- z. Consulte la stty -asalida

$ stty -a
speed 38400 baud; rows 50; columns 200; line = 0;
intr = ^C; [...] start = ^Q; stop = ^S; susp = ^Z; [...]
[...]

(salida abreviada) y sttypágina del manual:

   susp CHAR
          CHAR will send a terminal stop signal

Los procesos detenidos mediante la SIGSTOPseñal se pueden reiniciar enviando SIGCONT. Normalmente, es la lógica de control de trabajo de shell la que enviará SIGCONTy se encargará de otras manipulaciones necesarias involucradas fgy bgcomandos que ignoramos.

FooF
fuente