¿Cómo escribir un script bash, que inicia sesión en otra máquina para hacer cosas?

11

¿Es posible escribir un script bash, que

  1. se iniciaría desde la máquina A, iniciará sesión en una máquina B diferente mediante ssh (ambas máquinas A y B serían máquinas Linux),
  2. copia algunos archivos en la máquina B
  3. ejecuta una secuencia de comandos de Python en estas máquinas.
  4. transfiere los resultados a la máquina A
  5. se desconecta de la máquina B.

¿Es esto técnicamente factible?

Aufwind
fuente

Respuestas:

15

Por supuesto que es factible:

scp file user@host:
ssh user@host path_to_script
scp user@host:file_to_copy ./

y eso es...

Pero hay un problema: se le pedirá la contraseña tres veces. Para evitar que pueda generar claves ssh y autorizar a los usuarios mediante estas claves.

Para generar la ejecución de claves ssh ssh-keygen -t rsa, responda preguntas y copie la clave pública al host remoto (máquina B) en el ~/.ssh/authorized_keysarchivo. La clave privada debe guardarse en ~/.ssh/id_rsala máquina local (A).

pbm
fuente
Si las claves públicas no son una opción, puede hacer algo grosero para minimizar las solicitudes de contraseña comocat file | ssh user@host 'cat > /destination/of/file; /path/to/script &>/dev/null; cat results' > /destination/of/results
Patrick
Si desea usar la contraseña, siempre puede usar la agrupación de conexiones de OpenSSH definiendo ControlMaster=yesy ControlPath=/path/to/socketfile, y luego iniciar una conexión ssh con -fpara ejecutar un ssh en segundo plano. Indique a todas las conexiones SSH posteriores que usen el mismo archivo de socket.
jsbillings
4

Es posible hacer todo en una sola sshconexión / sesión:

ssh user@host "cat > remote_dst; command; cat remote_src" < local_src > local_dst

Esto:

  1. Copias local_srca remote_dst,
  2. Ejecuta command,
  3. Copias remote_srca local_dst.

Pero si commandsigue escribiendo stdout, el resultado también estará en local_dst. Si commandlee la entrada de stdin, recibirá y EOF.

jfg956
fuente
3

Si bien puede hacer esto dentro de una sola sesión ssh, es un poco complicado combinar la copia de archivos con los comandos en ejecución.

La forma más fácil de abordar esta tarea es ejecutar sesiones SSH separadas para las tres operaciones:

rsync -a inputs/ machineB:inputs/
ssh machineB 'some command -i inputs -o outputs'
rsync -a machineB:outputs/ outputs/

Esto requiere autenticarse en la máquina B tres veces. La forma recomendada de evitar la autenticación varias veces es usar la función de uso compartido de conexiones en las versiones modernas de OpenSSH: inicie una conexión maestra a B de una vez por todas y deje que SSH se conecte automáticamente a esa conexión maestra. Agregue ControlMaster autoy una ControlPathlínea a su~/.ssh/config , luego inicie una conexión maestra en segundo plano, luego realice sus tareas.

ssh -fN machineB                         # start a master connection in the background
# Subsequent connections will be slaves to the existing master connection
rsync -a inputs/ machineB:inputs/
ssh machineB 'some command -i inputs -o outputs'
rsync -a machineB:outputs/ outputs/

En lugar de usar scp o rsync para copiar archivos, puede ser más fácil montar el sistema de archivos remoto en SSHFS . Esto se encargará de configurar una conexión maestra, por cierto (suponiendo que haya configurado su ~/.ssh/configcomo se indicó anteriormente).

mkdir /net/machineB
sshfs machineB: /net/machineB
cp -Rp inputs /net/machineB/
ssh machibeB 'some command -i inputs -o outputs'
cp -Rp /net/machineB/outputs .
Gilles 'SO- deja de ser malvado'
fuente