En Linux, la forma de evitar un proceso en segundo plano desde que se detuvo después de cerrar cliente SSH
-
08-07-2019 - |
Pregunta
Estoy trabajando en una máquina linux a través de SSH (Putty).Necesito dejar un proceso que se ejecuta durante la noche, así que pensé que podría hacer que al iniciar el proceso en segundo plano (con un signo & al final del comando) y redirigir stdout a un archivo.Para mi sorpresa, que no funciona.Tan pronto como se cierre la ventana de Putty, el proceso se detiene.
¿Cómo puedo evitar que eso suceda??
Solución
Echa un vistazo a " nohup " programa.
Otros consejos
Recomendaría usar GNU Screen . Le permite desconectarse del servidor mientras todos sus procesos continúan ejecutándose. No sé cómo viví sin él antes de saber que existía.
Cuando se cierra la sesión, el proceso recibe la señal SIGHUP que aparentemente no está captando. Puede usar el comando nohup
al iniciar el proceso o el comando incorporado bash disown -h
después de iniciar el proceso para evitar que esto suceda:
> help disown
disown: disown [-h] [-ar] [jobspec ...]
By default, removes each JOBSPEC argument from the table of active jobs.
If the -h option is given, the job is not removed from the table, but is
marked so that SIGHUP is not sent to the job if the shell receives a
SIGHUP. The -a option, when JOBSPEC is not supplied, means to remove all
jobs from the job table; the -r option means to remove only running jobs.
daemonize? nohup? ¿PANTALLA? (tmux ftw, la pantalla es basura ;-)
Simplemente haga lo que todas las demás aplicaciones han hecho desde el principio: doble tenedor.
# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid: 1
# jobs
# disown
bash: disown: current: no such job
¡Bang! Hecho :-) He usado esto innumerables veces en todo tipo de aplicaciones y en muchas máquinas antiguas. Puede combinarse con redirecciones y otras cosas para abrir un canal privado entre usted y el proceso.
Crear como coproc.sh:
#!/bin/bash
IFS=
run_in_coproc () {
echo "coproc[$1] -> main"
read -r; echo $REPLY
}
# dynamic-coprocess-generator. nice.
_coproc () {
local i o e n=${1//[^A-Za-z0-9_]}; shift
exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
(("\$@")&) <&$i >&$o 2>&$e
$n=( $o $i $e )
COPROC
}
# pi-rads-of-awesome?
for x in {0..5}; do
_coproc COPROC$x run_in_coproc $x
declare -p COPROC$x
done
for x in COPROC{0..5}; do
. /dev/stdin <<RUN
read -r -u \${$x[0]}; echo \$REPLY
echo "$x <- main" >&\${$x[1]}
read -r -u \${$x[0]}; echo \$REPLY
RUN
done
y luego
# ./coproc.sh
declare -a COPROC0='([0]="21" [1]="16" [2]="23")'
declare -a COPROC1='([0]="24" [1]="19" [2]="26")'
declare -a COPROC2='([0]="27" [1]="22" [2]="29")'
declare -a COPROC3='([0]="30" [1]="25" [2]="32")'
declare -a COPROC4='([0]="33" [1]="28" [2]="35")'
declare -a COPROC5='([0]="36" [1]="31" [2]="38")'
coproc[0] -> main
COPROC0 <- main
coproc[1] -> main
COPROC1 <- main
coproc[2] -> main
COPROC2 <- main
coproc[3] -> main
COPROC3 <- main
coproc[4] -> main
COPROC4 <- main
coproc[5] -> main
COPROC5 <- main
Y ahí tienes, engendras lo que sea. el < (:) abre una tubería anónima a través de la sustitución del proceso, que muere, pero la tubería se pega porque tiene un identificador. Usualmente hago un sleep 1
en lugar de :
porque es un poco picante, y obtengo un & Quot; archivo ocupado & Quot; error: nunca ocurre si se ejecuta un comando real (por ejemplo, command true
)
" heredoc sourcing " ;:
. /dev/stdin <<EOF
[...]
EOF
Esto funciona en cada shell que he probado, incluyendo busybox / etc (initramfs). Nunca lo había visto antes, lo descubrí de forma independiente mientras pinchaba, ¿quién sabía que la fuente podía aceptar argumentos? Pero a menudo sirve como una forma de evaluación mucho más manejable, si existe tal cosa.
nohup blah &
¡Sustituya el nombre del proceso por bla!
Personalmente, me gusta el comando 'lote'.
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
Esto lo guarda en segundo plano y luego le envía los resultados por correo. Es parte de cron.
Como otros han señalado, para ejecutar un proceso en segundo plano para que pueda desconectarse de su sesión SSH, debe hacer que el proceso en segundo plano se disocie correctamente de su terminal de control, que es el pseudo-tty que la sesión SSH usos.
Puede encontrar información sobre procesos de demonización en libros como Stevens '" Advanced Network Program, Vol 1, 3rd Edn " o " Programación avanzada de Unix " ;.
Hace poco (en los últimos años) tuve que lidiar con un programa recalcitrante que no se demonizó correctamente. Terminé lidiando con eso creando un programa de demonización genérico, similar a nohup pero con más controles disponibles.
Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...]
-V print version and exit
-a output files in append mode (O_APPEND)
-b both output and error go to output file
-c create output files (O_CREAT)
-d dir change to given directory
-e file error file (standard error - /dev/null)
-h print help and exit
-i file input file (standard input - /dev/null)
-k fd-list keep file descriptors listed open
-m umask set umask (octal)
-o file output file (standard output - /dev/null)
-s sig-list ignore signal numbers
-t truncate output files (O_TRUNC)
-p print daemon PID on original stdout
-x output files must be new (O_EXCL)
El doble guión es opcional en sistemas que no utilizan la función GNU getopt (); es necesario (o debe especificar POSIXLY_CORRECT en el entorno) en Linux, etc. Dado que el doble guión funciona en todas partes, es mejor usarlo.
Todavía puede ponerse en contacto conmigo (nombre punto apellido en gmail punto com) si desea la fuente de daemonize
.
Sin embargo, el código ahora está (finalmente) disponible en GitHub en mi SOQ (Pila
Repositorio de preguntas de desbordamiento) como archivo daemonize-1.10.tgz
en el
paquetes
subdirectorio.
Si usa la pantalla para ejecutar un proceso como root, tenga cuidado con la posibilidad de ataques de elevación de privilegios. Si su propia cuenta se ve comprometida de alguna manera, habrá una forma directa de hacerse cargo de todo el servidor.
Si este proceso necesita ejecutarse regularmente y tiene suficiente acceso en el servidor, una mejor opción sería usar cron para ejecutar el trabajo. También puede usar init.d (el super demonio) para comenzar su proceso en segundo plano, y puede finalizar tan pronto como se haga.
En un sistema basado en Debian (en la máquina remota) Instalar:
sudo apt-get install tmux
Uso:
tmux
ejecuta los comandos que quieras
Para cambiar el nombre de la sesión:
Ctrl + B luego $
establecer nombre
Para salir de la sesión:
Ctrl + B luego D
(esto deja la sesión tmux). Luego, puede cerrar sesión en SSH.
Cuando necesite volver / verificarlo nuevamente, inicie SSH e ingrese
tmux attach session_name
Te llevará de vuelta a tu sesión de tmux.
nohup
es muy bueno si quieres registrar sus datos en un archivo.Pero cuando se pasa a segundo plano no puede asignarle una contraseña si los guiones pedir.Yo creo que hay que probar screen
.es una utilidad que puedes instalar en tu distribución de linux usando yum, por ejemplo, en CentOS yum install screen
entonces tener acceso a su servidor a través de la masilla u otro software, en su tipo de la cáscara screen
.Se abrirá la pantalla[0] en la masilla.A hacer su trabajo.Puede crear más de pantalla[1], la pantalla[2], etc, en la misma sesión de putty.
Comandos básicos que usted necesita saber:
A la pantalla de inicio
pantalla
A crear siguiente pantalla
ctrl+a+c
Para mover a next pantalla creó
ctrl+a+n
A detach
ctrl+a+d
Durante el trabajo cerca de tu masilla.Y la próxima vez cuando usted inicia sesión a través de la masilla tipo
pantalla -r
Para volver a conectar a la pantalla, y usted puede ver su proceso aún en marcha en la pantalla.Y para salir de la pantalla de tipo #de salida.
Para más detalles, ver man screen
.
Para la mayoría de los procesos, puede pseudo-demonizar usando este viejo truco de línea de comandos de Linux:
# ((mycommand &)&)
Por ejemplo:
# ((sleep 30 &)&)
# exit
Luego, inicie una nueva ventana de terminal y:
# ps aux | grep sleep
Mostrará que sleep 30
todavía se está ejecutando.
Lo que ha hecho es iniciar el proceso como hijo de un niño, y cuando sale, el comando nohup
que normalmente desencadenaría el proceso de salida no cae en cascada hacia el nieto, dejándolo como un proceso huérfano, aún en ejecución.
Prefiero esto & "; configúralo y olvídalo &"; enfoque, no es necesario tratar con screen
, <=>, tmux, redirección de E / S, o cualquiera de esas cosas.
Nohup permite que un proceso del cliente no se elimine si se elimina un proceso principal, para discutir cuando cierre la sesión. Aún mejor todavía use:
nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohup hace que el proceso que usted inicia sea inmune a la terminación que su sesión SSH y sus procesos secundarios se anulan al cerrar sesión. El comando que le proporcioné le proporciona una forma de almacenar el pid de la aplicación en un archivo pid para que pueda matarlo correctamente más tarde y permita que el proceso se ejecute después de que haya cerrado sesión.
Usar pantalla. Es muy simple de usar y funciona como vnc para terminales. http://www.bangmoney.org/presentations/screen.html
Si también está dispuesto a ejecutar aplicaciones X, use xpra junto con " screen < !> quot ;.
también iría por el programa de pantalla (sé que otra respuesta fue pantalla pero esta es una finalización)
no solo el hecho de que & amp ;, ctrl + z bg disown, nohup, etc. puede darte una desagradable sorpresa de que cuando cierres sesión, el trabajo seguirá siendo asesinado (no sé por qué, pero me pasó a mí , y no se molestó porque cambié a usar la pantalla, pero supongo que la solución anthonyrisinger como doble bifurcación resolvería eso), también la pantalla tiene una ventaja importante sobre solo el fondo:
screen will background your process without losing interactive control to it
y por cierto, esta es una pregunta que nunca haría en primer lugar :) ... uso la pantalla desde el principio para hacer cualquier cosa en cualquier Unix ... yo (casi) NUNCA trabajo en un shell de Unix / Linux sin iniciar la pantalla primero ... y debería parar ahora, o comenzaré una presentación interminable de lo que es una buena pantalla y qué puede hacer por usted ... búsquela usted mismo, vale la pena;)
También existe el comando daemon del paquete libslack de código abierto.
daemon
es bastante configurable y se preocupa por todas las tediosas cosas del demonio, como el reinicio automático, el registro o el manejo de archivos pid.
Agregue esta cadena a su comando: > & amp; - 2 > & amp; - < & amp; - & amp ;. > & amp; - significa cierre stdout. 2 & Gt; & Amp; - significa estrecho stderr. < & amp; - significa cierre stdin. & amp; significa correr en segundo plano. Esto también funciona para iniciar un trabajo mediante programación mediante ssh:
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
Usé el comando de pantalla. Este enlace tiene detalles sobre cómo hacer esto
https://www.rackaid.com / blog / linux-screen-tutorial-and-how-to / # empezando
La respuesta aceptada sugiere usar nohup . Prefiero sugerir el uso de pm2 . Usar pm2 sobre nohup tiene muchas ventajas, como mantener viva la aplicación, mantener archivos de registro para la aplicación y muchas otras funciones más. Para obtener más detalles consulte esto .
Para instalar pm2 necesita descargar npm . Para el sistema basado en Debian
sudo apt-get install npm
y para Redhat
sudo yum install npm
O puede seguir estas instrucciones . Después de instalar npm , úselo para instalar pm2
npm install pm2@latest -g
Una vez hecho esto, puede iniciar su aplicación
$ pm2 start app.js # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py # Start, Daemonize and auto-restart application (Python)
Para la supervisión del proceso, utilice los siguientes comandos:
$ pm2 list # List all processes started with PM2
$ pm2 monit # Display memory and cpu usage of each app
$ pm2 show [app-name] # Show all informations about application
Administre procesos utilizando el nombre de la aplicación o la identificación del proceso o administre todos los procesos juntos:
$ pm2 stop <app_name|id|'all'|json_conf>
$ pm2 restart <app_name|id|'all'|json_conf>
$ pm2 delete <app_name|id|'all'|json_conf>
Los archivos de registro se pueden encontrar en
$HOME/.pm2/logs #contain all applications logs
Los archivos ejecutables binarios también se pueden ejecutar usando pm2. Tienes que hacer un cambio en el archivo jason. Cambie "exec_interpreter" : "node"
a "exec_interpreter" : "none".
(consulte la sección de atributos ).
#include <stdio.h>
#include <unistd.h> //No standard C library
int main(void)
{
printf("Hello World\n");
sleep (100);
printf("Hello World\n");
return 0;
}
Compilando el código anterior
gcc -o hello hello.c
y ejecútelo con np2 en segundo plano
pm2 start ./hello
En systemd / Linux, systemd-run es Una buena herramienta para iniciar procesos independientes de la sesión. Los que odian odiarán