procesos - Linux: evita que un proceso en segundo plano se detenga después de cerrar el cliente SSH
screen debian (20)
Estoy trabajando en una máquina Linux a través de SSH (Putty). Necesito dejar un proceso en ejecución durante la noche, así que pensé que podría hacerlo iniciando el proceso en segundo plano (con un signo al final del comando) y redirigiendo stdout a un archivo. Para mi sorpresa, eso no funciona. Tan pronto como cierro la ventana Putty, el proceso se detiene.
¿Cómo puedo evitar que eso suceda?
Agregue esta cadena a su comando:> & - 2> & - <& - &. > & - significa cerrar la salida estándar. 2> & - significa cerrar stderr. <& - significa cerrar stdin. & significa ejecutar en segundo plano. Esto funciona para iniciar un trabajo programáticamente a través de ssh, también:
$ ssh myhost ''sleep 30 >&- 2>&- <&- &''
# ssh returns right away, and your sleep job is running remotely
$
Como otros han señalado, para ejecutar un proceso en segundo plano para que pueda desconectarse de su sesión de SSH, necesita que el proceso en segundo plano se desasocie de su terminal de control, que es el pseudo-tty que utiliza la sesión de SSH.
Puede encontrar información acerca de los procesos de demonización en libros como el "Programa de red avanzada de Stevens, Vol 1, 3rd Edn" o la "Programación avanzada de Unix" de Rochkind.
Hace poco (en el último par de años) tuve que lidiar con un programa recalcitrante que no se desmonta correctamente. Terminé lidiando con eso creando un programa genérico de demonización, 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 tablero es opcional en sistemas que no usan la función getopt () de GNU; es necesario (o debe especificar POSIXLY_CORRECT en el entorno) en Linux, etc. Como el doble guión funciona en todas partes, es mejor usarlo.
Aún puedes contactarme (nombre de punto, apellido en gmail punto com) si quieres la fuente de daemonize
.
Sin embargo, el código ahora (finalmente) está disponible en GitHub en mi SOQ ( Questions) como archivo daemonize-1.10.tgz
en el subdirectorio de packages .
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 de bash no está disponible 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.
Echa un vistazo al programa " nohup ".
En systemd / Linux, systemd-run es una buena herramienta para iniciar procesos independientes de la sesión. Personas con odio van a odiar
En un sistema basado en Debian (en la máquina remota), instale:
sudo apt-get install tmux
Uso:
tmux
ejecuta los comandos que quieras
Para renombrar la sesión:
Ctrl + B luego $
escoger un nombre
Para salir de la sesión:
Ctrl + B luego D
(Esto deja la sesión de tmux). A continuación, puede cerrar sesión en SSH.
Cuando necesite volver / verificarlo nuevamente, inicie SSH y entre
adjuntar nombre de sesión
Te llevará de regreso a tu sesión de tmux.
La respuesta aceptada sugiere usar nohup . Prefiero sugerir el uso de pm2 . El uso de pm2 sobre nohup tiene muchas ventajas, como mantener la aplicación activa, mantener los archivos de registro de la aplicación y muchas más funciones. Para más detalles mira esto .
Para instalar pm2 necesitas descargar npm . Para el sistema basado en Debian
sudo apt-get install npm
y para Redhat
sudo yum install npm
O puedes seguir estas instrucciones . Después de instalar npm utilízalo para instalar pm2.
npm install pm2@latest -g
Una vez hecho esto, puede iniciar su aplicación por
$ pm2 start app.js # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py # Start, Daemonize and auto-restart application (Python)
Para la monitorización de procesos use 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 los procesos usando 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 utilizando pm2. Tienes que hacer un cambio en el archivo jason. Cambie "exec_interpreter" : "node"
, a "exec_interpreter" : "none".
(ver 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 ejecutarlo con np2 en el fondo
pm2 start ./hello
Nohup permite que el proceso de un cliente no se elimine si se interrumpe el proceso principal, por un argumento cuando se cierra sesión. Aún mejor aún usar:
nohup /bin/sh -c "echo /$/$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohup hace que el proceso que inicie sea inmune a la terminación, en el que su sesión de SSH y sus procesos secundarios se eliminan al cerrar la sesión. El comando que di le proporciona una forma en que puede almacenar el pid de la aplicación en un archivo pid para que pueda eliminarlo correctamente más tarde y permitir que el proceso se ejecute después de que se haya desconectado.
Para la mayoría de los procesos, puede realizar una pseudo daemonización con este antiguo truco de línea de comandos de Linux:
# ((mycommand &)&)
Por ejemplo:
# ((sleep 30 &)&)
# exit
Luego comienza una nueva ventana de terminal y:
# ps aux | grep sleep
Mostrará que el sleep 30
todavía se está ejecutando.
Lo que has hecho es iniciar el proceso como hijo de un niño, y cuando sales, el comando nohup
que normalmente activaría el proceso para salir no llega al nieto, dejándolo como un proceso huérfano, todavía corriendo.
Prefiero este enfoque de "configúrelo y olvídelo", no hay necesidad de lidiar con nohup
, screen
, tmux, I / o redirection, o cualquiera de esas cosas.
Personalmente, me gusta el comando ''batch''.
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
Esto lo mete en segundo plano y luego te envía los resultados. Es una parte de cron.
Si también está dispuesto a ejecutar aplicaciones X, use xpra junto con "pantalla".
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 debe ejecutarse regularmente y usted 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 daemon) para iniciar el proceso en segundo plano, y puede terminar tan pronto como se haya completado.
También está el comando daemon del paquete libslack de código abierto.
daemon
es bastante configurable y se preocupa por todas las cosas tediosas de daemon como el reinicio automático, el registro o el manejo de archivos pid.
También me gustaría ir al programa de pantalla (sé que alguna otra respuesta fue pantalla, pero esto es una compleción)
no solo el hecho de que &, ctrl + z bg disown, nohup, etc. puede darte una desagradable sorpresa de que cuando te desconectes del trabajo todavía se eliminará el trabajo (no sé por qué, pero me sucedió a mí y no me molestó con ello porque cambié a usar la pantalla, pero supongo que la solución de anthonyrisinger como doble forking resolvería eso), también la pantalla tiene una gran ventaja sobre la puesta a tierra:
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 ... i (casi) NUNCA trabajo en un shell de Unix / Linux sin la pantalla de inicio Primero ... y debería detenerme ahora, o comenzaré una presentación interminable de lo que es una buena pantalla y lo que puedo hacer por ti ... búsquelo usted mismo, vale la pena;)
Usa la pantalla. Es muy simple de usar y funciona como vnc para terminales. http://www.bangmoney.org/presentations/screen.html
Utilicé el comando de pantalla. Este enlace tiene detalles sobre cómo hacer esto.
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting
Yo recomendaría usar la pantalla GNU . Le permite desconectarse del servidor mientras todos sus procesos continúan ejecutándose. No sé cómo viví sin eso antes de saber que existía.
daemonizar? nohup? ¿PANTALLA? (tmux ftw, pantalla es basura ;-)
Simplemente haga lo que cualquier otra aplicación ha hecho desde el principio: doble horquilla.
# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid: 1
# jobs
# disown
bash: disown: current: no such job
¡Explosión! Hecho :-) He usado esto innumerables veces en todo tipo de aplicaciones y en muchas máquinas antiguas. Puede combinar 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 entonces
# ./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í van, engendren 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 atasca porque tiene un identificador. Por lo general, hago un sleep 1
lugar de :
porque es un poco delicado, y obtendré un error de "archivo ocupado": nunca ocurre si se ejecuta un comando real (por ejemplo, command true
)
"abastecimiento heredoc":
. /dev/stdin <<EOF
[...]
EOF
Esto funciona en todos los shell individuales 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
es muy bueno si desea registrar sus datos en un archivo. Pero cuando pasa a segundo plano, no puede darle una contraseña si sus scripts lo piden. Creo que debes probar la screen
. es una utilidad que puede instalar en su distribución de Linux usando yum, por ejemplo, en la yum install screen
CentOS yum install screen
luego acceda a su servidor a través de masilla u otro software, en su screen
tipo shell. Se abrirá la pantalla [0] en masilla. Haz tu trabajo. Puede crear más pantalla [1], pantalla [2], etc. en la misma sesión de masilla.
Comandos básicos que necesitas saber:
Para iniciar la pantalla
pantalla
Para crear la siguiente pantalla.
Ctrl + a + c
Para moverte a la pantalla externa que creaste.
Ctrl + a + n
A d etach
Ctrl + a + d
Durante el trabajo cierra tu masilla. Y la próxima vez que inicie sesión a través de tipo masilla
pantalla -r
Para volver a conectarse a su pantalla, y puede ver que su proceso aún se ejecuta en la pantalla. Y para salir de la pantalla escribe #exit.
Para más detalles vea la man screen
.
nohup blah &
Sustituye tu nombre de proceso por bla!