Para cualquiera que tenga el mismo problema: recuerde que incluso si escribe yourExecutable &y las salidas siguen apareciendo en la pantalla y Ctrl+Cno parece detener nada, simplemente escriba disown;y presione ciegamente Enterincluso si la pantalla se desplaza con las salidas y no puede ver qué estas escribiendo El proceso será desautorizado y podrá cerrar el terminal sin que el proceso muera.
Nav
Respuestas:
1367
Usando el control de trabajo de bash para enviar el proceso a un segundo plano:
Ctrl+ Zpara detener (pausar) el programa y volver al shell.
bg para ejecutarlo en segundo plano.
disown -h [job-spec]donde [especificación-trabajo] es el número de trabajo (como %1para el primer trabajo en ejecución; encuentre su número con el jobscomando) para que el trabajo no se elimine cuando se cierra el terminal.
Como la pregunta era cómo "ponerlo debajo de nohup", disown -htal vez sea la respuesta más exacta: "hacer que Disown se comporte más como nohup (es decir, los trabajos permanecerán en el árbol de proceso de su shell actual hasta que salga de su shell) Esto le permite ver todos los trabajos que comenzó este shell ". (de [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )
Dr. Jan-Philip Gehrcke
8
¿Cómo recupero el trabajo más tarde? Puedo verlo corriendo usando ps -e.
Paulo Casaretto
26
No puede ver la salida de un trabajo después de que disown, desconocer, hace que un proceso sea un demonio, lo que significa que la entrada / salida estándar se redirige a / dev / null. Entonces, si planea rechazar un trabajo, es mejor comenzar con el inicio de sesión en un archivo, por ejemplomy_job_command | tee my_job.log
rustyx
8
¿es posible de alguna manera hacer algo como 'my_job_command | tee my_job.log ' después de que el comando ya se esté ejecutando?
arod
23
disowndisocia cualquier tubería del proceso. Para volver a conectar las tuberías, use gdbcomo se describe en este hilo . Más específicamente, esta publicación .
mbrownnyc
185
Supongamos que, por alguna razón, Ctrl+ Ztampoco funciona, vaya a otra terminal, busque la identificación del proceso (usando ps) y ejecute:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOPsuspenderá el proceso y SIGCONTreanudará el proceso, en segundo plano. Entonces, cerrar ambos terminales no detendrá su proceso.
Sí, eso es un problema del sistema operativo, kill no funciona con Cygwin en Windows.
Pungs
66
También es muy útil si el trabajo se inicia desde otra sesión ssh.
Amir Ali Akbari
55
Solo recuerde hacer el disown %1en la primera terminal antes de cerrarlo.
Fred
1
Esto es útil ya que comencé una interfaz gráfica con una consola (en mi caso, comencé desde konsole kwindespués de un bloqueo sin pensar en las consecuencias). Entonces, si detuviera a kwin, ¡todo se habría congelado y no tendría posibilidades de correr bg!
Michele
@fred No hice esto y parecía seguir funcionando. ¿Posible o golpeé el PID incorrecto?
Nadie
91
El comando para separar un trabajo en ejecución del shell (= lo hace nohup) es disowny un comando de shell básico.
Desde bash-manpage (man bash):
disown [-ar] [-h] [jobspec ...]
Sin opciones, cada especificación de trabajo se elimina de la tabla de trabajos activos. Si se da la opción -h, cada especificación de trabajo no se elimina de la tabla, sino que se marca para que SIGHUP no se envíe al trabajo si el shell recibe un SIGHUP. Si no hay ninguna especificación de trabajo, y no se proporciona la opción -a ni la opción -r, se utiliza el trabajo actual. Si no se proporciona una especificación de trabajo, la opción -a significa eliminar o marcar todos los trabajos; la opción -r sin un argumento jobspec restringe la operación a trabajos en ejecución. El valor de retorno es 0 a menos que una especificación de trabajo no especifique un trabajo válido.
Eso significa que un simple
disown -a
eliminará todos los trabajos de la tabla de trabajos y los hará nohup
disown -aelimina todos los trabajos. Un simple disownsolo elimina el trabajo actual. Como dice la página del manual en la respuesta.
Rune Schjellerup Philosof
73
Estas son buenas respuestas anteriores, solo quería agregar una aclaración:
No puedes disownun pid o un proceso, eres disownun trabajo, y esa es una distinción importante.
Un trabajo es algo que es una noción de un proceso que se adjunta a un shell, por lo tanto, debe lanzar el trabajo en segundo plano (no suspenderlo) y luego rechazarlo.
Solo para AIXy Solaris. "Las versiones de nohup de AIX y Solaris tienen una opción -p que modifica un proceso en ejecución para ignorar las señales SIGHUP futuras. A diferencia de lo que se describe anteriormente de bash, nohup -p acepta ID de proceso". Fuente
AlikElzin-kilaka
27
La respuesta de Node es realmente genial, pero dejó abierta la pregunta de cómo se puede redireccionar stdout y stderr. Encontré una solución en Unix y Linux , pero tampoco está completa. Me gustaría fusionar estas dos soluciones. Aquí está:
Para mi prueba, hice un pequeño script bash llamado loop.sh, que imprime el pid de sí mismo con un minuto de sueño en un bucle infinito.
$./loop.sh
Ahora obtenga el PID de este proceso de alguna manera. Por ps -C loop.shlo general, es lo suficientemente bueno, pero está impreso en mi caso.
Ahora podemos cambiar a otro terminal (o presionar ^ Z y en el mismo terminal). Ahora gdbdebe adjuntarse a este proceso.
$ gdb -p <PID>
Esto detiene el script (si se está ejecutando). Se puede verificar su estado ps -f <PID>, donde el STATcampo es 'T +' (o en el caso de ^ Z 'T'), lo que significa (man ps (1))
T Stopped, either by a job control signal or because it is being traced+ is in the foreground process group(gdb) call close(1)
$1 =0
Cerrar (1) devuelve cero en caso de éxito.
(gdb) call open("loop.out",01102,0600)
$6 =1
Abrir (1) devuelve el nuevo descriptor de archivo si tiene éxito.
Esta apertura es igual a open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). En lugar de O_RDWRO_WRONLYpodría aplicarse, pero /usr/sbin/lsofdice 'u' para todos los controladores de archivos std * ( FDcolumna), que es O_RDWR.
Verifiqué los valores en /usr/include/bits/fcntl.h archivo de encabezado.
El archivo de salida podría abrirse O_APPEND, como nohuplo haría, pero esto no se sugiere man open(2)debido a posibles problemas de NFS.
Si obtenemos -1 como valor de retorno, call perror("")imprime el mensaje de error. Si necesitamos el errno, use p errnogdb comand.
Si queremos, podemos redirigir stderr a otro archivo, si queremos usar call close(2)y call open(...)nuevamente usar un nombre de archivo diferente.
Ahora bashse debe liberar el adjunto y podemos salir gdb:
(gdb) detachDetaching from program:/bin/bash, process <PID>(gdb) q
Si el script fue detenido por gdbotro terminal, continúa ejecutándose. Podemos volver a la terminal de loop.sh. Ahora no escribe nada en la pantalla, sino que se ejecuta y escribe en el archivo. Tenemos que ponerlo en un segundo plano. Entonces presiona ^Z.
^Z[1]+Stopped./loop.sh
(Ahora estamos en el mismo estado que si ^Zse hubiera presionado al principio).
Ahora podemos verificar el estado del trabajo:
$ ps -f 24522
UID PID PPID C STIME TTY STAT TIME CMD<UID><PID><PPID>011:16 pts/36 S 0:00/bin/bash ./loop.sh
$ jobs[1]+Stopped./loop.sh
Por lo tanto, el proceso debe ejecutarse en segundo plano y desconectarse de la terminal. El número en la jobssalida del comando entre corchetes identifica el trabajo dentro bash. Podemos usar los siguientes bashcomandos integrados aplicando un signo '%' antes del número de trabajo:
$ bg %1[1]+./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID><PID><PPID>011:16 pts/36 S 0:00/bin/bash ./loop.sh
Y ahora podemos abandonar la llamada de bash. El proceso continúa ejecutándose en segundo plano. Si abandonamos su PPID se convierte en 1 (proceso init (1)) y el terminal de control se vuelve desconocido.
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID><PID>1011:16? S 0:00/bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>...
loop.sh <PID> truey 0u CHR 136,3638/dev/pts/36(deleted)
loop.sh <PID> truey 1u REG 0,26112715008411/home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,3638/dev/pts/36(deleted)
COMENTARIO
El material gdb se puede automatizar creando un archivo (por ejemplo, loop.gdb) que contiene los comandos y ejecutar gdb -q -x loop.gdb -p <PID>. Mi loop.gdb se ve así:
Muy informativo, y es probable que funcione bien en casos simples. Pero tenga cuidado, los casos más complejos pueden fallar miserablemente. Tuve uno de esos hoy: mi proceso había generado otro proceso que produjo el resultado (presumiblemente para stderr), pero había conectado stdout para la comunicación con su maestro. La redirección de los FDs maestros no tuvo efecto porque el niño había heredado stderr, y al cerrar la salida estándar del niño falló el maestro que estaba esperando en el otro extremo de la tubería. X- | Bettern conoce bien tus procesos antes de intentarlo.
cmaster - reinstalar a monica el
@cmaster Puede verificar si un identificador se redirige utilizando lsof(el nombre del identificador del archivo es pipe, no como /dev/pts/1) o mediante ls -l /proc/<PID>/fd/<fd>(esto muestra el enlace simbólico del identificador). Además, los subprocesos aún pueden no tener salidas redirigidas, que deberían redirigirse a un archivo.
Luego probé los siguientes comandos y funcionó muy bien
Ejecute algo de SOMECOMMAND, digamos /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.
Ctrl+ Zpara detener (pausar) el programa y volver al shell.
bg para ejecutarlo en segundo plano.
disown -h para que el proceso no se elimine cuando se cierra el terminal.
Escriba exitpara salir del shell porque ahora está listo para comenzar, ya que la operación se ejecutará en segundo plano en su propio proceso, por lo que no está vinculada a un shell.
Este proceso es el equivalente a la ejecución nohup SOMECOMMAND.
Esto funcionó bien. Continuó ejecutando mi proceso incluso después de cerrar las ventanas de terminal. Tenemos ksh como shell predeterminado, por lo que los comandos bgy disownno funcionaron.
Creo que el comportamiento de Disown -a es cortar el apego con todos los trabajos. Sin embargo, no cierra las canalizaciones stdin / stdout, lo que significa que el proceso aún intentará escribir (/ leer) desde la terminal
Kelthar
-2
Esto funcionó para mí en Ubuntu Linux mientras estaba en tcshell.
yourExecutable &
y las salidas siguen apareciendo en la pantalla yCtrl+C
no parece detener nada, simplemente escribadisown;
y presione ciegamenteEnter
incluso si la pantalla se desplaza con las salidas y no puede ver qué estas escribiendo El proceso será desautorizado y podrá cerrar el terminal sin que el proceso muera.Respuestas:
Usando el control de trabajo de bash para enviar el proceso a un segundo plano:
bg
para ejecutarlo en segundo plano.disown -h [job-spec]
donde [especificación-trabajo] es el número de trabajo (como%1
para el primer trabajo en ejecución; encuentre su número con eljobs
comando) para que el trabajo no se elimine cuando se cierra el terminal.fuente
disown -h
tal vez sea la respuesta más exacta: "hacer que Disown se comporte más como nohup (es decir, los trabajos permanecerán en el árbol de proceso de su shell actual hasta que salga de su shell) Esto le permite ver todos los trabajos que comenzó este shell ". (de [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )disown
, desconocer, hace que un proceso sea un demonio, lo que significa que la entrada / salida estándar se redirige a / dev / null. Entonces, si planea rechazar un trabajo, es mejor comenzar con el inicio de sesión en un archivo, por ejemplomy_job_command | tee my_job.log
disown
disocia cualquier tubería del proceso. Para volver a conectar las tuberías, usegdb
como se describe en este hilo . Más específicamente, esta publicación .Supongamos que, por alguna razón, Ctrl+ Ztampoco funciona, vaya a otra terminal, busque la identificación del proceso (usando
ps
) y ejecute:SIGSTOP
suspenderá el proceso ySIGCONT
reanudará el proceso, en segundo plano. Entonces, cerrar ambos terminales no detendrá su proceso.fuente
disown %1
en la primera terminal antes de cerrarlo.kwin
después de un bloqueo sin pensar en las consecuencias). Entonces, si detuviera a kwin, ¡todo se habría congelado y no tendría posibilidades de correrbg
!El comando para separar un trabajo en ejecución del shell (= lo hace nohup) es
disown
y un comando de shell básico.Desde bash-manpage (man bash):
Eso significa que un simple
eliminará todos los trabajos de la tabla de trabajos y los hará nohup
fuente
disown -a
elimina todos los trabajos. Un simpledisown
solo elimina el trabajo actual. Como dice la página del manual en la respuesta.Estas son buenas respuestas anteriores, solo quería agregar una aclaración:
No puedes
disown
un pid o un proceso, eresdisown
un trabajo, y esa es una distinción importante.Un trabajo es algo que es una noción de un proceso que se adjunta a un shell, por lo tanto, debe lanzar el trabajo en segundo plano (no suspenderlo) y luego rechazarlo.
Problema:
Consulte http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ para obtener una discusión más detallada sobre el control de trabajos de Unix.
fuente
Lamentablemente,
disown
es específico de bash y no está disponible en todos los shells.Ciertos tipos de Unix (por ejemplo, AIX y Solaris) tienen una opción en el
nohup
comando en sí que se puede aplicar a un proceso en ejecución:Ver http://en.wikipedia.org/wiki/Nohup
fuente
AIX
ySolaris
. "Las versiones de nohup de AIX y Solaris tienen una opción -p que modifica un proceso en ejecución para ignorar las señales SIGHUP futuras. A diferencia de lo que se describe anteriormente de bash, nohup -p acepta ID de proceso". FuenteLa respuesta de Node es realmente genial, pero dejó abierta la pregunta de cómo se puede redireccionar stdout y stderr. Encontré una solución en Unix y Linux , pero tampoco está completa. Me gustaría fusionar estas dos soluciones. Aquí está:
Para mi prueba, hice un pequeño script bash llamado loop.sh, que imprime el pid de sí mismo con un minuto de sueño en un bucle infinito.
Ahora obtenga el PID de este proceso de alguna manera. Por
ps -C loop.sh
lo general, es lo suficientemente bueno, pero está impreso en mi caso.Ahora podemos cambiar a otro terminal (o presionar ^ Z y en el mismo terminal). Ahora
gdb
debe adjuntarse a este proceso.Esto detiene el script (si se está ejecutando). Se puede verificar su estado
ps -f <PID>
, donde elSTAT
campo es 'T +' (o en el caso de ^ Z 'T'), lo que significa (man ps (1))Cerrar (1) devuelve cero en caso de éxito.
Abrir (1) devuelve el nuevo descriptor de archivo si tiene éxito.
Esta apertura es igual a
open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
. En lugar deO_RDWR
O_WRONLY
podría aplicarse, pero/usr/sbin/lsof
dice 'u' para todos los controladores de archivos std * (FD
columna), que esO_RDWR
.Verifiqué los valores en /usr/include/bits/fcntl.h archivo de encabezado.
El archivo de salida podría abrirse
O_APPEND
, comonohup
lo haría, pero esto no se sugiereman open(2)
debido a posibles problemas de NFS.Si obtenemos -1 como valor de retorno,
call perror("")
imprime el mensaje de error. Si necesitamos el errno, usep errno
gdb comand.Ahora podemos verificar el archivo recién redirigido.
/usr/sbin/lsof -p <PID>
huellas dactilares:Si queremos, podemos redirigir stderr a otro archivo, si queremos usar
call close(2)
ycall open(...)
nuevamente usar un nombre de archivo diferente.Ahora
bash
se debe liberar el adjunto y podemos salirgdb
:Si el script fue detenido por
gdb
otro terminal, continúa ejecutándose. Podemos volver a la terminal de loop.sh. Ahora no escribe nada en la pantalla, sino que se ejecuta y escribe en el archivo. Tenemos que ponerlo en un segundo plano. Entonces presiona^Z
.(Ahora estamos en el mismo estado que si
^Z
se hubiera presionado al principio).Ahora podemos verificar el estado del trabajo:
Por lo tanto, el proceso debe ejecutarse en segundo plano y desconectarse de la terminal. El número en la
jobs
salida del comando entre corchetes identifica el trabajo dentrobash
. Podemos usar los siguientesbash
comandos integrados aplicando un signo '%' antes del número de trabajo:Y ahora podemos abandonar la llamada de bash. El proceso continúa ejecutándose en segundo plano. Si abandonamos su PPID se convierte en 1 (proceso init (1)) y el terminal de control se vuelve desconocido.
COMENTARIO
El material gdb se puede automatizar creando un archivo (por ejemplo, loop.gdb) que contiene los comandos y ejecutar
gdb -q -x loop.gdb -p <PID>
. Mi loop.gdb se ve así:O puede usar el siguiente revestimiento:
Espero que esta sea una descripción bastante completa de la solución.
fuente
lsof
(el nombre del identificador del archivo espipe
, no como/dev/pts/1
) o mediantels -l /proc/<PID>/fd/<fd>
(esto muestra el enlace simbólico del identificador). Además, los subprocesos aún pueden no tener salidas redirigidas, que deberían redirigirse a un archivo.Para enviar el proceso en ejecución a nohup ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid
no me funcionóLuego probé los siguientes comandos y funcionó muy bien
Ejecute algo de SOMECOMMAND, digamos
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.Ctrl+ Zpara detener (pausar) el programa y volver al shell.
bg
para ejecutarlo en segundo plano.disown -h
para que el proceso no se elimine cuando se cierra el terminal.Escriba
exit
para salir del shell porque ahora está listo para comenzar, ya que la operación se ejecutará en segundo plano en su propio proceso, por lo que no está vinculada a un shell.Este proceso es el equivalente a la ejecución
nohup SOMECOMMAND
.fuente
En mi sistema AIX, intenté
Esto funcionó bien. Continuó ejecutando mi proceso incluso después de cerrar las ventanas de terminal. Tenemos ksh como shell predeterminado, por lo que los comandos
bg
ydisown
no funcionaron.fuente
bg
- esto pondrá el trabajo en segundo plano y volverá al proceso de ejecucióndisown -a
- esto cortará todos los archivos adjuntos con el trabajo (para que pueda cerrar el terminal y aún se ejecutará)Estos sencillos pasos le permitirán cerrar el terminal mientras mantiene el proceso en ejecución.
No se pondrá
nohup
(según mi comprensión de su pregunta, no la necesita aquí).fuente
Esto funcionó para mí en Ubuntu Linux mientras estaba en tcshell.
CtrlZ pausarlo
bg
correr en segundo planojobs
para obtener su número de trabajonohup %n
donde n es el número de trabajofuente
nohup: failed to run command '%1': No such file or directory