Ssh, ejecute un comando al iniciar sesión y luego ¿Permanezca conectado?

29

Intenté esto con esperar, pero no funcionó: cerró la conexión al final.

¿Podemos ejecutar un script a través de ssh que inicie sesión en máquinas remotas, ejecute un comando y no se desconecte?

Entonces ssh en una máquina, cd a tal y tal directorio, y luego ejecute un comando, y permanezca conectado.

-Jonathan

(espero que lo use)

#!/usr/bin/expect -f
set password [lrange $argv 0 0]
spawn ssh root@marlboro "cd /tmp; ls -altr | tail"
expect "?assword:*"
send -- "$password\r"
send -- "\r"
interact
Jonathan
fuente
9
¿Soy solo yo o estás "automatizando" la autenticación de contraseña de esta manera, en lugar de usar pubkeys u otro método sensato?
Grawity

Respuestas:

25

¿Agregar un ; /bin/bashal final de su línea de comando en el lado remoto? Es decir:

spawn ssh -t root@marlboro "cd /tmp; ls -altr | tail; /bin/bash -i"

Aún mejor, cambie el .bashrc de la raíz para que sea algo así:

PROMPT_COMMAND="cd /tmp && ls -altr | tail ; unset PROMPT_COMMAND"

:)

Bill Weiss
fuente
2
Es posible que desee agregar -ia esa fiesta.
Teddy
Sí, supongo :)
Bill Weiss
Cuando hago eso, la finalización de tabulación se rompe en el nuevo shell (incluso con "-i"). ¿Alguna idea de por qué / cómo solucionarlo?
Coderer
1
Probé mi nueva respuesta aquí, funciona muy bien. Un poco áspero, pero funciona.
Bill Weiss
77
Intenta ssh -tasignar una pty.
Pausado hasta nuevo aviso.
4

Si está de acuerdo con hacer esto en Python, pexpect tiene un ejemplo que hace casi exactamente lo que está pidiendo:

import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('[email protected]')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Para hacer esto con ssh en lugar de ftp, querrás un código similar al siguiente (los archivos de ejemplo en pexpect tienen muchos más detalles e información, pero aquí están los conceptos básicos):

import pexpect
child = pexpect.spawn ('ssh root@marlboro')
child.expect ('Password:')
child.sendline ('password')
child.expect ('prompt# ')
child.sendline ('cd /tmp')
child.expect ('prompt# ')
child.sendline ('ls -altr | tail')
child.expect ('prompt# ')
print child.before, child.after   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

No me malinterpreten, ME ENCANTA esperar (especialmente autoexpect), pero Python es muchísimo más fácil de asimilar.

Jed Daniels
fuente
Yo también estoy haciendo la transición de esperar a pexpect. Python ahora es mucho más omnipresente.
JM Becker
4

La forma probablemente más fácil y limpia de ingresar a un servidor, generar un shell interactivo y ejecutar comandos dentro de ese shell es crear un archivo rc personalizado para bash.

En su archivo bashrc personalizado en el servidor, primero obtenga el archivo predeterminado y luego agregue sus comandos personalizados, p. Ej.

~ / .bashrc_custom:

. ~/.bashrc
cd dir/
workon virtualenvproject

Luego puede iniciar su sesión SSH de esta manera:

$ ssh -t server "/bin/bash --rcfile ~/.bashrc_custom -i"

La -topción fuerza una asignación de pseudo-tty, de modo que cosas como completar la tabulación funcionen.

La --rcfileopción especifica qué archivo rc cargar en lugar del predeterminado. Importante: debe colocar "argumentos de doble guión" en la línea de comando antes de las opciones de un solo carácter para que se reconozca.

El -iargumento para / bin / bash está ahí para invocar un shell interactivo.

Danilo Bargen
fuente
en realidad no. ¿Qué hacer si quiero ejecutar diferentes comandos para cada conexión?
Eugen Konkov
1

Si alguien quiere información sobre lo que está sucediendo en segundo plano, debería consultar el manual de sshd:

Cuando un usuario inicia sesión con éxito, sshd hace lo siguiente:

  1. Si el inicio de sesión está en un tty, y no se ha especificado ningún comando, imprime la última hora de inicio de sesión y / etc / motd (a menos que se evite en el archivo de configuración o por ~ / .hushlogin; consulte la sección ARCHIVOS).
  2. Si el inicio de sesión está en un tty, registra el tiempo de inicio de sesión.
  3. Comprueba / etc / nologin y / var / run / nologin; si existe, imprime el contenido y se cierra (a menos que sea root).
  4. Cambios para ejecutarse con privilegios de usuario normales.
  5. Configura el entorno básico.
  6. Lee el archivo ~ / .ssh / environment, si existe, y los usuarios pueden cambiar su entorno. Vea la opción PermitUserEnvironment en sshd_config (5).
  7. Cambios en el directorio de inicio del usuario.
  8. Si ~ / .ssh / rc existe, lo ejecuta; si no existe / etc / ssh / sshrc, lo ejecuta; de lo contrario se ejecuta xauth (1). Los archivos `` rc '' reciben el protocolo de autenticación X11 y la cookie en la entrada estándar. Ver SSHRC, a continuación.
  9. Ejecuta el shell o el comando del usuario .

https://www.freebsd.org/cgi/man.cgi?sshd(8)#LOGIN_PROCESS

Gerry
fuente
0

En general, debe evitar usar ssh de esta manera, ya que anula su propósito.
Hacer un

ssh-add -l | grep "file_of_your_rsa_priv_key_here"

para ver si su clave aparece en el grupo de sesiones activas de ssh o agréguela usted mismo (con ssh-add).

Kounavi
fuente