Pregunta ¿Cómo desconecto un proceso de la Terminal, por completo?


Utilizo Tilda (terminal desplegable) en Ubuntu como mi "central de comandos", más o menos como otros podrían usar GNOME Do, Quicksilver o Launchy.

Sin embargo, estoy luchando con la forma de desconectar por completo un proceso (por ejemplo, Firefox) de la terminal desde la que se lanzó, es decir, evitar que dicho proceso (no) infantil

  • termina cuando se cierra el terminal de origen
  • "contamina" la terminal de origen a través de STDOUT / STDERR

Por ejemplo, para iniciar Vim en una ventana de terminal "adecuada", he intentado con un script simple como el siguiente:

exec gnome-terminal -e "vim $@" &> /dev/null &

Sin embargo, eso todavía causa contaminación (también, pasar un nombre de archivo no parece funcionar).


274


origen


Esa, también, es una buena pregunta. Creo que es justo considerar a Bash como un lenguaje de programación, aunque de hecho el alcance de esta pregunta probablemente sea más del lado de los administradores de sistemas ...
Este es un duplicado de esta pregunta stackoverflow.com/questions/285015/... - Dana the Sane
dup de:superuser.com/questions/177218/... - behrooz
Su caso de uso no describe el desapego completo, per se. - jiggunjer


Respuestas:


Ante todo; una vez que haya comenzado un proceso, puede hacer un fondo deteniéndolo primero (golpear Ctrl-Z) y luego escribir bg para que se reanude en el fondo. Ahora es un "trabajo", y es stdout/stderr/stdin todavía están conectados a su terminal.

Puede iniciar un proceso como trasfondo inmediatamente añadiendo un "y" al final del mismo:

firefox &

Para ejecutarlo en segundo plano silenciado, usa esto:

firefox </dev/null &>/dev/null &

Alguna información adicional:

nohup es un programa que puedes usar para ejecutar su aplicación con de modo que stdout / stderr se puede enviar a un archivo en su lugar y de tal manera que al cerrar el script principal no se atienda al hijo. Sin embargo, debe haber tenido la previsión de haberlo usado antes de iniciar la aplicación. Por el camino nohup funciona, no puedes solo aplicarlo a un proceso en ejecución.

disown es un bash incorporado que elimina un trabajo de shell de la lista de trabajos del shell. Lo que esto básicamente significa es que no puedes usar fg, bg ya no es así, pero lo más importante es que, cuando cierras el caparazón, no se cuelga o envías un SIGHUP a ese niño más. diferente a nohup, disown es usado después el proceso ha sido iniciado y retrocedido.

Lo que tu hipocresía hacer, es cambiar el stdout / stderr / stdin de un proceso después de haberlo lanzado. Al menos no desde el caparazón. Si inicia su proceso y le dice que su stdout es su terminal (que es lo que hace de manera predeterminada), entonces ese proceso está configurado para enviar a su terminal. Su caparazón no tiene nada que ver con la configuración FD de los procesos, eso es simplemente algo que el proceso mismo maneja. El proceso en sí puede decidir si cierra su stdout / stderr / stdin o no, pero no puede usar su caparazón para obligarlo a hacerlo.

Para gestionar el resultado de un proceso en segundo plano, tiene muchas opciones de secuencias de comandos, y probablemente sea "el primer no" el que se acerque a la mente. Pero para los procesos interactivos comienzas pero te olvidas de silenciar (firefox < /dev/null &>/dev/null &) no puedes hacer mucho, realmente.

Te recomiendo que obtengas GNU screen. Con la pantalla, puede cerrar el shell que se está ejecutando cuando la salida del proceso se convierta en una molestia y abrir uno nuevo (^Ac)


Ah, y por cierto, no uses "$@"donde lo estás usando".

$@medio, $1, $2, $3 ..., que convertiría tu comando en:

gnome-terminal -e "vim $1" "$2" "$3" ...

Probablemente eso no es lo que quieres porque solo tomas uno argumento. Utilizar $1 para mostrar que su script solo puede manejar un argumento.

Es realmente difícil hacer que múltiples argumentos funcionen correctamente en el escenario que usted dio (con el gnome-terminal -e) porque -e toma solo un argumento, que es una cadena de comandos de shell. Tendría que codificar sus argumentos en uno. La mejor y más robusta, pero bastante clásica, es así:

gnome-terminal -e "vim $(printf "%q " "$@")"

308



¡Muchas gracias por esto! Lamentablemente, solo puedo aceptar una respuesta. Terminé con "nohup $ @ &> / dev / null &" y "alias wvim = 'launch.sh gnome-terminal -x vim'"
Qué respuesta fantásticamente detallada e informativa. +1 - Teekin
@ Hi-Angel cuando cierras un shell bash interactivo, golpea HUP todos los trabajos activos. Cuando usted ^ Z y bg un proceso sigue siendo un trabajo, ya sea uno de fondo. Para eliminarlo como un trabajo, use disown, entonces el proceso seguirá viviendo después de que cierres el caparazón ya que bash ya no lo usará. - lhunath
No usará $* en lugar de $@ arreglar el problema de las cadenas separadas ya? - sjas
Lo que no puede hacer es cambiar el stdout / stderr / stdin de un proceso después de haberlo lanzado. - No es exactamente cierto. Utilizar reptyr para esto. - Stefan Seidel


nohup cmd &

nohup separa el proceso por completo (daemonizes)


190



Aunque sucinto es valioso, la integridad es más valiosa. Aunque nohup es un coreutil de GNU, una respuesta bash-only (o una nota acerca de que no hay uno) sería apropiada aquí. Buena respuesta, no obstante. - Limited Atonement
nohup solo ignora el SIGHUP señal. Ejecuta el proceso normalmente. Sin daemonización. - nemo
@nemo Lo que significa que el proceso no está separado, sino que se separaría (y sería un niño de init) si el caparazón salió ... ¿verdad? - Noldorin
@Noldorin Sí. Ignorar SIGHUP, que se envía cuando el shell finaliza, dejará el proceso secundario ejecutándose y siendo reubicado en init. - nemo
@nemo nohup también silencia entradas / salidas estándar. Haga un seguimiento con repudio para desprenderse por completo. - jiggunjer


Si estás usando bash, tratar disown [Jobpec]; ver bash (1).

Otro enfoque que puedes probar es at now. Si no eres superusuario, tu permiso para usar at puede estar restringido


51



"repudio" no parece ser un comando bash interno (no está disponible en mi máquina, y yo uso bash). "nohup", como sugirió Ben, podría ser una manera mucho mejor (y estándar) de hacer esto.
nunca pensé en usar "at", ¡gracias por la idea! - cadrian
at para delegar la ejecución a otra persona, ¡me gusta! +1 - Ninsuo
Como punto de referencia, esto funciona en zsh también. - Coderer
También, disown no parece tener el efecto deseado con gnome-terminal-disownLos procesos ed todavía se matan cuando sale el terminal. Me encantaría saber por qué / cómo. - Kyle Strand


Al leer estas respuestas, estaba bajo la impresión inicial de que emitía nohup <command> & sería suficiente Ejecutando zsh en gnome-terminal, encontré que nohup <command> & no evitó que mi caparazón matara procesos secundarios al salir. A pesar de que nohup es útil, especialmente con shells no interactivos, solo garantiza este comportamiento si el proceso hijo no restablece su controlador para el SIGHUP señal.

En mi caso, nohup debería haber evitado que las señales de colgado lleguen a la aplicación, pero la aplicación secundaria (VMWare Player en este caso) estaba restableciendo su SIGHUP entrenador de animales. Como resultado, cuando el emulador de terminal sale, aún podría matar sus subprocesos. Esto solo se puede resolver, que yo sepa, al asegurar que el proceso se elimine de la tabla de trabajos del shell. Si nohup se anula con un shell incorporado, como es a veces el caso, esto puede ser suficiente, sin embargo, en el caso de que no sea ...


disown es un shell incorporado en bash, zshy ksh93,

<command> &
disown

o

<command> &; disown

si prefieres una sola línea. Esto tiene el efecto generalmente deseable de eliminar el subproceso de la tabla de trabajos. Esto le permite salir del emulador de terminal sin señalar accidentalmente el proceso secundario. No importa lo que SIGHUP controlador parece, esto no debería matar a su proceso hijo.

Después de la desaprobación, el proceso sigue siendo un elemento secundario de tu emulador de terminal (jugar con pstree si quieres ver esto en acción), pero después de que el emulador de terminal sale, deberías verlo adjunto al proceso init. En otras palabras, todo es como debería ser, y como supuestamente quieres que sea.

Qué hacer si tu caparazón no es compatible disown? Yo recomendaría encarecidamente cambiar a uno que sí lo haga, pero a falta de esa opción, tiene algunas opciones.

  1. screen y tmux puede resolver este problema, pero son soluciones mucho más pesadas, y no me gusta tener que ejecutarlas para una tarea tan simple. Son mucho más adecuados para situaciones en las que desea mantener un tty, generalmente en una máquina remota.
  2. Para muchos usuarios, puede ser deseable ver si su shell admite una capacidad como zsh's setopt nohup. Esto se puede usar para especificar que SIGHUPno se debe enviar a los trabajos en la tabla de trabajos cuando el shell se cierra. Puede aplicar esto justo antes de salir del shell, o agregarlo a la configuración del shell como ~/.zshrc si siempre lo deseas encendido.
  3. Encuentra una forma de editar la tabla de trabajos. No pude encontrar una manera de hacer esto en tcsh o csh, que es algo inquietante
  4. Escribe un pequeño programa de C para desviar y exec(). Esta es una solución muy pobre, pero la fuente solo debe consistir en un par de docenas de líneas. A continuación, puede pasar comandos como argumentos de línea de comando al programa C, y así evitar una entrada específica del proceso en la tabla de trabajos.

34





  1. nohup $ COMANDO y

  2. $ COMANDO y repudiar

  3. comando setsid

He usado el número 2 durante mucho tiempo, pero el número 3 funciona igual de bien. Además, el rechazo tiene un indicador 'nohup' de '-h', puede descartar todos los procesos con '-a' y puede descartar todos los procesos en ejecución con '-ar'.

El silenciamiento se logra mediante '$ COMMAND &> / dev / null'.

¡Espero que esto ayude!


23





Creo que la pantalla podría resolver su problema


9





en tcsh (y tal vez también en otros shells), puede usar paréntesis para separar el proceso.

Compare esto:

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

A esto:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

Esto elimina firefox de la lista de trabajos, pero todavía está vinculado a la terminal; si inició sesión en este nodo a través de 'ssh', intentar cerrar la sesión seguirá bloqueando el proceso de ssh.


8