Ejecutar instrucción if en máquina remota

Estoy intentando ejecutar un set de commands en una máquina remota, que incluye una instrucción if. Estoy usando esto para cerrar una list de instancias de kvm. La primera línea debería estar bien, pero podría ser más bonita, el rest necesita ayuda.

ssh root@kvmsrv 'virsh shutdown $host 2> /dev/null; virsh destroy $host 2> /dev/null; sleep 2; virsh undefine $host 2> /dev/null' # Also needs to be run on remote machine # to disconnect iscsi iscsiadm -m session | grep $host if [ $? == 0 ]; then iscsiadm -m node -T $stserver.$host -u fi # then on local machine tid=`ssh root@storage1 'cat /proc/net/iet/volume' | grep $host | head -1 | awk '{print $1}' | awk -F: '{print $2}'` if [ $tid ]; then echo "Deleting tid:$tid from $stserver." ssh root@$stserver "ietadm --op delete --tid=$tid" fi 

Creo que podría hacer lo mismo para la segunda parte, solo separarlo; pero si alguien va a leer mi código más tarde, probablemente se estén rascando la cabeza …

¿Hay alguna manera de formatear todo esto para que sea legible y aún tenga sentido y para que todos los commands remotos se ejecuten correctamente?

Related of "Ejecutar instrucción if en máquina remota"

  1. Coloque su larga y compleja secuencia de commands en su propio script de shell, llamémoslo virsh-shutdown-remote.sh

  2. Ejecute ssh y use la networkingirección de input para ejecutar el script:

     ssh root@kvmsrv < virsh-shutdown-remote.sh 

Poner los commands en un script es una buena idea en cualquier caso.

Como un consejo extra, en lugar de esto:

 iscsiadm -m session | grep $host if [ $? == 0 ]; then iscsiadm -m node -T $stserver.$host -u fi 

Puede escribir lo mismo más simple y más corto en una sola línea:

 iscsiadm -m session | grep $host && iscsiadm -m node -T $stserver.$host -u 

Puede usar HEREDOCS , por ejemplo:

 ssh root@kvmsrv <<EOF virsh shutdown $host 2> /dev/null virsh destroy $host 2> /dev/null sleep 2 virsh undefine $host 2> /dev/null # to disconnect iscsi iscsiadm -m session | grep $host if [ \$? == 0 ] ; then iscsiadm -m node -T $stserver.$host -u fi EOF 

Tenga en count que escapé $? de lo contrario, sería evaluado por su shell local y no desde su shell remoto. Como $host parece estar definido localmente, no tendrás que escaping de él.

Solo un pequeño comentario, aunque no lo pediste. Puede ejecutar remotamente commands de virsh, sin necesidad de ssh explícitamente en el host, por ejemplo:

 virsh -c qemu+ssh://root@kvmsrv/system destroy host 

trabajará. Tampoco necesita ssh, ya que libvirt le permite autenticarse con ssl certs insteads.

¿Tal vez solo agregue comentarios para explicar cosas que (deberían ser) obvias? Hago esto regularmente en guiones para recordarle a mi propio ignorante qué estaba haciendo cuando escribí la cosa [censurada] en primer lugar.

Bueno, la respuesta simple es que en realidad es posible reescribir ssh root@kvmsrv 'cmd1; cmd2; cmd3' ssh root@kvmsrv 'cmd1; cmd2; cmd3' ssh root@kvmsrv 'cmd1; cmd2; cmd3' como:

 ssh root@kvmsrv ' cmd1 cmd2 cmd3 ' 

Lo único que debe recordar es que las comillas simples "dentro" de las comillas simples deben expressse como: '\'' . Ejemplos:

 ssh localhost ' echo hi whoami ls -ld / var="'\''" echo "$var" if [ $? == 0 ]; then echo "escaping single quote worked" fi ' # get single quote from file and print it echo "'" > sqfile ssh localhost ' #set -xv echo hi cat sqfile var="$(cat sqfile)" echo "$var" ' # pass a single quote to the remote host and print it # while keeping the outer single quotes for the ssh command escsquote="'\''" squote="'" squote="'${squote//\'/${escsquote}}'" # bash ssh localhost 'sh -c '\'' #set -xv echo hi echo "$1" '\''' _ "$squote"