¿Es posible escribir un script bash que
- se inicie desde la máquina A, inicie sesión en una máquina B por ssh (ambas máquinas A y B serían máquinas Linux),
- copia algunos archivos en la máquina B
- ejecuta una secuencia de comandos de Python, una secuencia de comandos de Python determinada en estas máquinas.
- transfiere los resultados a la máquina A
- cierra la sesión de la máquina B.
¿Es esto técnicamente factible?
Respuesta
Por supuesto que es factible:
scp file user@host: ssh user@host path_to_script scp user@host:file_to_copy ./
y eso es todo …
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 ssh Las claves ejecutan ssh-keygen -t rsa
, responden preguntas y copian la clave pública al host remoto (máquina B) en el archivo ~/.ssh/authorized_keys
. La clave privada debe guardarse en ~/.ssh/id_rsa
en la máquina local (A).
Comentarios
Respuesta
Es posible hacer todo en una sola ssh
conexión / sesión:
ssh user@host "cat > remote_dst; command; cat remote_src" < local_src > local_dst
Esto:
- Copias
local_src
aremote_dst
, - Ejecuta
command
, - Copia
remote_src
alocal_dst
.
Pero si command
escribe en stdout
, el resultado también estará en local_dst
. Si command
lee la entrada de stdin
, recibirá y EOF
.
Respuesta
Si bien puede hacer esto dentro de una sola sesión ssh, es un poco complicado combinar la copia de archivos con 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 machineB tres veces. La forma recomendada de evitar la autenticación varias veces es utilizar la función de conexión compartida en las versiones modernas de OpenSSH: inicie una conexión maestra con B de una vez por todas y deje que SSH se acople automáticamente a esa conexión maestra. Agrega ControlMaster auto
y una línea ControlPath
a tu ~/.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 r 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 (asumiendo que «ha configurado su ~/.ssh/config
como se indica arriba).
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 .
cat file | ssh user@host 'cat > /destination/of/file; /path/to/script &>/dev/null; cat results' > /destination/of/results
ControlMaster=yes
yControlPath=/path/to/socketfile
, y luego inicie una conexión ssh con-f
para ejecutar un ssh en segundo plano. Indique a todas las conexiones SSH posteriores que utilicen el mismo archivo de socket.