bash - trabajos - ver ejecuciones en segundo plano linux
¿Cómo elimino una sesión ssh en segundo plano/desconectada? (10)
Estoy usando la sinergia del programa junto con un túnel ssh
Funciona, solo tengo que abrir una consola y escribir estos dos comandos:
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost
porque im lazy hice un Bash-Script que se ejecuta con un solo clic sobre un ícono:
#!/bin/bash
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost
el Bash-Script anterior también funciona, pero ahora también quiero matar la sinergia y el túnel ssh mediante un clic de ratón, así que tengo que guardar los PID de sinergia y ssh en el archivo para matarlos más tarde:
#!/bin/bash
mkdir -p /tmp/synergyPIDs || exit 1
rm -f /tmp/synergyPIDs/ssh || exit 1
rm -f /tmp/synergyPIDs/synergy || exit 1
[ ! -e /tmp/synergyPIDs/ssh ] || exit 1
[ ! -e /tmp/synergyPIDs/synergy ] || exit 1
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
echo $! > /tmp/synergyPIDs/ssh
synergyc localhost
echo $! > /tmp/synergyPIDs/synergy
Pero los archivos de este script están vacíos.
¿Cómo obtengo los PID de ssh y la sinergia?
(Intento evitar las combinaciones de ps aux | grep ... | awk ... | sed ...
, tiene que haber una manera más fácil).
Acabo de encontrar este hilo y quería mencionar la utilidad de Linux "pidof":
$ pidof init
1
Basado en la muy buena respuesta de @ghoti, aquí hay una secuencia de comandos más simple (para probar) que utiliza los sockets de control SSH sin la necesidad de configuración adicional:
#!/bin/bash
if ssh -fN -MS /tmp/mysocket -L localhost:12345:otherHost:12345 otherUser@otherHost; then
synergyc localhost
ssh -S /tmp/mysocket -O exit otherHost
fi
synergyc
solo se iniciará si el túnel se ha establecido con éxito, que se cerrará tan pronto como vuelva la synergyc
. Aunque la solución carece de informes de errores adecuados.
Con todo respeto a los usuarios de pgrep
, pkill
, ps | awk
ps | awk
, etc, hay una manera mucho mejor.
Considere que si confía en ps -aux | grep ...
ps -aux | grep ...
para encontrar un proceso, corre el riesgo de una colisión. Puede tener un caso de uso donde sea poco probable, pero como regla general, no es el camino a seguir.
SSH proporciona un mecanismo para administrar y controlar procesos en segundo plano. Pero como tantas otras cosas SSH, es una característica "avanzada", y muchas personas (al parecer, de las otras respuestas aquí) desconocen su existencia.
En mi propio caso de uso, tengo una estación de trabajo en casa en la que quiero dejar un túnel que se conecta a un proxy HTTP en la red interna de mi oficina, y otro que me da acceso rápido a las interfaces de administración en servidores compartidos . Así es como puedes crear los túneles básicos, iniciados desde casa:
$ ssh -fNT -L8888:proxyhost:8888 -R22222:localhost:22 officefirewall
$ ssh -fNT -L4431:www1:443 -L4432:www2:443 colocatedserver
Esto causa que ssh se encienda en sí mismo, dejando los túneles abiertos. Pero si el túnel se va, estoy atascado, y si quiero encontrarlo, tengo que analizar mi lista de procesos y en casa tengo el ssh "correcto" (en caso de que accidentalmente haya lanzado varios que se vean) similar).
En cambio, si quiero administrar conexiones múltiples, utilizo la opción de configuración ControlMaster
de SSH, junto con la opción de línea de comandos -O
para control. Por ejemplo, con lo siguiente en mi archivo ~/.ssh/config
,
host officefirewall colocatedserver
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
los comandos ssh de arriba, cuando se ejecutan, dejarán spoor en ~/.ssh/cm_sockets/
que puede proporcionar acceso para el control, por ejemplo:
$ ssh -O check officefirewall
Master running (pid=23980)
$ ssh -O exit officefirewall
Exit request sent.
$ ssh -O check officefirewall
Control socket connect(/home/ghoti/.ssh/cm_socket/[email protected]:22): No such file or directory
Y en este punto, el túnel (y el control de la sesión SSH) se ha ido, sin la necesidad de usar un martillo ( kill
, killall
, pkill
, etc.).
Devolviendo esto a tu caso de uso ...
Está estableciendo el túnel a través del cual desea que syngergyc
converse con syngergys
en el puerto TCP 12345. Para eso, haría algo como lo siguiente.
Agregue una entrada a su archivo ~/.ssh/config
:
Host otherHosttunnel
HostName otherHost
User otherUser
LocalForward 12345 otherHost:12345
RequestTTY no
ExitOnForwardFailure yes
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
Tenga en cuenta que la opción de línea de comando -L
se maneja con la palabra clave LocalForward
, y las líneas Control {Master, Path} se incluyen para asegurarse de tener el control una vez que se establece el túnel.
Entonces, puedes modificar tu script bash a algo como esto:
#!/bin/bash
if ! ssh -f -N otherHosttunnel; then
echo "ERROR: couldn''t start tunnel." >&2
exit 1
else
synergyc localhost
ssh -O exit otherHosttunnel
fi
La opción -f
recorre el túnel, dejando un socket en su ControlPath para cerrar el túnel más tarde. Si el ssh falla (que puede deberse a un error de red o ExitOnForwardFailure
), no hay necesidad de salir del túnel, pero si no falló ( else
), se inicia synergyc y luego el túnel se cierra después de que sale.
También es posible que desee ver si la opción SSH LocalCommand
podría utilizarse para iniciar synergyc
directamente desde su archivo de configuración ssh.
Este es más un caso especial para Synergyc (y la mayoría de los otros programas que intentan demonizarse a sí mismos). ¡Usando $! funcionaría, excepto que synergyc hace un syscall de clonación () durante la ejecución que le dará un nuevo PID distinto al que bash pensó que tenía. Si quieres evitar esto para poder usar $ !, entonces puedes decirle a synergyc que se quede en el forground y luego lo fondo.
synergyc -f -n mydesktop remoteip &
synergypid=$!
synergyc también hace algunas otras cosas como autorestart que es posible que desee desactivar si está tratando de administrarlo.
Otra opción es usar pgrep para encontrar el PID del proceso ssh más nuevo
ssh -fNTL 8073:localhost:873 otherUser@OtherHost
tunnelPID=$(pgrep -n -x ssh)
synergyc localhost
kill -HUP $tunnelPID
Puede soltar el -f
, que lo hace ejecutarlo en segundo plano, luego ejecutarlo con eval
y forzarlo al fondo usted mismo.
A continuación, puede agarrar el pid
. Asegúrese de poner el &
dentro de la declaración de eval
.
eval "ssh -N -L localhost:12345:otherHost:12345 otherUser@OtherHost & "
tunnelpid=$!
Puede usar lsof para mostrar el pid del proceso que escucha el puerto 12345 en localhost:
lsof -t -i @localhost:12345 -sTCP:listen
Ejemplos:
PID=$(lsof -t -i @localhost:12345 -sTCP:listen)
lsof -t -i @localhost:12345 -sTCP:listen >/dev/null && echo "Port in use"
Puedes buscar el procedimiento ssh que está vinculado a tu puerto local, usando esta línea:
netstat -tpln | grep 127/.0/.0/.1:12345 | awk ''{print $7}'' | sed ''s#/.*##''
Devuelve el PID del proceso utilizando el puerto 12345 / TCP en localhost. Por lo tanto, no tiene que filtrar todos los resultados ssh
de ps
.
Si solo necesita comprobar, si ese puerto está vinculado, use:
netstat -tln | grep 127/.0/.0/.1:12345 >/dev/null 2>&1
Devuelve 1
si no está vinculado o 0
si alguien está escuchando este puerto.
así que no quiero agregar un & al final de los comandos ya que la conexión morirá si la consola wintow está cerrada ... así que terminé con un ps-grep-awk-sed-combo
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@otherHost
echo `ps aux | grep -F ''ssh -f -N -L localhost'' | grep -v -F ''grep'' | awk ''{ print $2 }''` > /tmp/synergyPIDs/ssh
synergyc localhost
echo `ps aux | grep -F ''synergyc localhost'' | grep -v -F ''grep'' | awk ''{ print $2 }''` > /tmp/synergyPIDs/synergy
(Podrías integrar grep en awk, pero ahora soy demasiado flojo)
Resumen rápido: no funcionará.
¡Mi primera idea es que debe iniciar los procesos en segundo plano para obtener sus PID con $!
.
Un patrón como
some_program &
some_pid=$!
wait $some_pid
podría hacer lo que necesites ... excepto que entonces ssh no estará en primer plano para pedir más frases de contraseña.
Bueno, entonces, es posible que necesites algo diferente después de todo. ssh -f
probablemente genere un nuevo proceso que tu caparazón nunca podrá saber al invocarlo de todos modos. Idealmente, ssh en sí mismo ofrecería una forma de escribir su PID en algún archivo.