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 el jobs
comando) para que el trabajo no se elimine cuando se cierra el terminal.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, use gdb
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:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP
suspenderá el proceso y SIGCONT
reanudará el proceso, en segundo plano. Entonces, cerrar ambos terminales no detendrá su proceso.
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 correr bg
!
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):
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 -a
elimina todos los trabajos. Un simple disown
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, eres disown
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:
% jobs
[1] running java
[2] suspended vi
% disown %1
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.
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:
nohup -p pid
AIX
y 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
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.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.
$ gdb -p <PID>
Esto detiene el script (si se está ejecutando). Se puede verificar su estado ps -f <PID>
, donde el STAT
campo 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_RDWR
O_WRONLY
podría aplicarse, pero /usr/sbin/lsof
dice 'u' para todos los controladores de archivos std * ( FD
columna), 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 nohup
lo 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 errno
gdb comand.
Ahora podemos verificar el archivo recién redirigido. /usr/sbin/lsof -p <PID>
huellas dactilares:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
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 bash
se debe liberar el adjunto y podemos salir gdb
:
(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q
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
.
^Z
[1]+ Stopped ./loop.sh
(Ahora estamos en el mismo estado que si ^Z
se 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> 0 11: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 jobs
salida del comando entre corchetes identifica el trabajo dentro bash
. Podemos usar los siguientes bash
comandos 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> 0 11: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> 1 0 11:16 ? S 0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey 0u CHR 136,36 38 /dev/pts/36 (deleted)
loop.sh <PID> truey 1u REG 0,26 1127 15008411 /home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,36 38 /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í:
call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit
O puede usar el siguiente revestimiento:
gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
Espero que esta sea una descripción bastante completa de la solución.
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.
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
.
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í).
Esto funcionó para mí en Ubuntu Linux mientras estaba en tcshell.
CtrlZ pausarlo
bg
correr en segundo plano
jobs
para obtener su número de trabajo
nohup %n
donde n es el número de trabajo
nohup: failed to run command '%1': No such file or directory
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.