Tengo una máquina local que se supone que debe hacer una sesión SSH en una master
máquina remota y luego otra sesión SSH interna desde master
cada uno de algunos remotos slaves
, y luego ejecutar 2 comandos, es decir, eliminar un directorio específico y recrearlo.
Tenga en cuenta que la máquina local tiene SSH sin contraseña para el maestro y el maestro tiene SSH sin contraseña para los esclavos. También todos los nombres de host son conocidos en .ssh/config
las máquinas locales / maestras y los nombres de host de los esclavos están slaves.txt
localmente y los leo desde allí.
Entonces, lo que hago y funciona es esto:
username="ubuntu"
masterHostname="myMaster"
while read line
do
#Remove previous folders and create new ones.
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition""
ssh -n $username@$masterHostname "ssh -t -t $username@$line "mkdir -p EC2_WORKSPACE/$project Input Output Partition""
#Update changed files...
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rsync --delete -avzh /EC2_NFS/$project/* EC2_WORKSPACE/$project""
done < slaves.txt
Este clúster está en Amazon EC2 y he notado que hay 6 sesiones SSH creadas en cada iteración, lo que induce un retraso significativo. Me gustaría combinar estos 3 comandos en 1 para obtener menos conexiones SSH. Así que intenté combinar los primeros 2 comandos en
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition && mkdir -p EC2_WORKSPACE/$project Input Output Partition""
Pero no funciona como se esperaba. Parece ejecutar el primero ( rm -rf Input Output Partition
) y luego sale de la sesión y continúa. ¿Que puedo hacer?
fuente
-J
opción que definiría su host de salto.Respuestas:
Considere que
&&
es un operador lógico. Lo hace no media "también de este comando" que significa "ejecutar este comando si el otro tuvo éxito".Eso significa que si el
rm
comando falla (lo que sucederá si alguno de los tres directorios no existe), entoncesmkdir
no se ejecutará. Esto no suena como el comportamiento que desea; Si los directorios no existen, probablemente esté bien crearlos.Utilizar
;
El punto y coma
;
se usa para separar los comandos. Los comandos se ejecutan secuencialmente, esperando cada uno antes de continuar con el siguiente, pero su éxito o fracaso no tienen impacto entre ellos.Escape de citas internas
Las comillas dentro de otras comillas deben escaparse, de lo contrario, creará un punto final y un punto de inicio adicionales. Su comando:
Se convierte en:
Su comando actual, debido a la falta de comillas escapadas, debería estar ejecutándose:
si eso tiene éxito:
Notará que el resaltado de sintaxis muestra el comando completo en rojo aquí, lo que significa que todo el comando es la cadena que se pasa a ssh. Verifique su máquina local; puede tener los directorios
Input
Output
yPartition
dónde estaba ejecutando esto.fuente
&
comandos de causas se ejecutan en el fondo, lo que significa que no se esperará a que finalicen antes de pasar al siguiente.Siempre puedes definir en tu jumpbox Multiplexación en OpenSSH
Para eso hacer en
/etc/ssh/ssh_config
:De esta manera, cualquier conexión consecutiva realizada al mismo servidor en los siguientes 30 minutos se realizará reutilizando la conexión ssh anterior.
También puede definirlo para una máquina o grupo de máquinas. Tomado del enlace proporcionado.
fuente
/tmp/
.man ssh
,ControlPath
,ControlMaster
yControlPersist
son opciones válidas para pasar unssh
comando usando-o
. Podría ser un caso de uso aún más preciso, configure la multiplexación en el primerssh
guión y recíclela para los demás, pero evite la penalización de rendimiento. Me pregunto cuál es el punto de referencia de la multiplexación VS no para 3 conexiones SSH, dado que "También hay un retraso significativo al abrir una nueva conexión"Puede poner todos sus comandos en un script separado en su servidor "maestro".
Guión maestro
Luego, en su script ssh, llámelo así: SSH Script
O si todos los archivos deben estar en la máquina inicial, podría hacer algo como esto:
script1
script2
ssh script
fuente
Hace algún tiempo, tuve la oportunidad de usar sockets de control como recomiendan las otras respuestas (esta respuesta es esencialmente una combinación de usar sockets de control como esta respuesta y scripts como esta respuesta ).
El caso de uso fue un truco:
authorized_keys
una tarea programada sobrescribía periódicamente al usuario objetivo y quería probar rápidamente las cosas sin pasar por la burocracia necesaria para agregar algo a ese archivo. Así que configuré un ciclo while que agregaba la clave a ese archivo según fuera necesario, ejecutaba mi prueba y cancelaba el ciclo. Sin embargo, habría una pequeña ventana donde la tarea programada sobrescribiría el archivo y mi bucle seguiría funcionandosleep
. Entonces, configurar un socket de control al inicio permitiría que mi script SSH más tarde sin problemas:Donde
setup-ssh.sh
es:Y
.ssh-config
:Y
run-test.sh
:La secuencia es así:
setup-ssh.sh
.setup-ssh.sh
busy-buclea los servidores hasta que todos tengan una configuración de socket de control. Elhosts
archivo simplemente enumera los nombres de host del servidor uno por línea.${CONFIG_DIR}/scripts/.ssh-config
, a menos que especifique ese archivo usando-F
, las conexiones SSH no lo usarán. Entonces, esto me permite usar el zócalo de control solo donde los necesito usando laF
opción.xargs
para distribuir la carga de trabajo a través de los servidores, comenzando nuevos trabajos tan pronto como finalicen los que se ejecutan.fuente