GNU/Linux >> Tutoriales Linux >  >> Linux

¿Ssh hace que el ciclo while se detenga?

Finalmente he logrado reducir un problema con el que he estado luchando durante algunas semanas. Uso SSH con "claves autorizadas" para ejecutar comandos de forma remota. Todo está bien, excepto cuando lo hago en un bucle while. El ciclo termina después de completar cualquier iteración con un comando ssh.

Durante mucho tiempo pensé que esto era una especie de rareza ksh, pero ahora descubrí que bash se comporta de manera idéntica.

Un pequeño programa de muestra para reproducir el problema. Esto se extrae de una implementación más grande que toma instantáneas y las replica entre los nodos de un clúster.

#!/bin/bash

set -x

IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool

ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG    " > /tmp/actionlist

#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
   echo ${RMT_FILESYSTEM}@${MARKER}
   [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
   echo Remote Command Return Code: $?
done

(Tenga en cuenta que hay un carácter TAB en la expresión de búsqueda grep según la definición del comportamiento de la opción "-H" de la lista zfs).

Mi muestra tiene algunos sistemas de archivos ZFS para la raíz donde todas las "zonas" tienen su sistema de archivos raíz en un conjunto de datos con un nombre similar a

PISCINA/zonas/app1zone
PISCINA/zonas/grupo2/app2zone

etc.

El ciclo anterior debería crear una instantánea para cada uno de los conjuntos de datos seleccionados, pero en su lugar, opera solo en el primero y luego sale.

Que el programa encuentre el número correcto de conjuntos de datos se puede confirmar fácilmente revisando el archivo "/tmp/actionlist" después de que exista el script.

Si el comando ssh se reemplaza, por ejemplo, por un comando echo, el ciclo itera a través de todas las líneas de entrada. O mi favorito:anteponga "eco" al comando ofensivo.

Si utilizo un bucle for en su lugar, también funciona, pero debido al tamaño potencial de la lista de conjuntos de datos, esto podría causar problemas con la longitud máxima de la línea de comando expandida.

¡Ahora estoy 99.999% seguro de que solo esos bucles con comandos ssh me dan problemas!

Tenga en cuenta que la iteración en la que se ejecuta el comando ssh se completa. Es como si los datos introducidos en el ciclo while se perdieran repentinamente... Si las primeras líneas de entrada no ejecutan un comando ssh, entonces el ciclo continúa hasta que realmente ejecuta el comando SSH.

En mi computadora portátil donde estoy probando esto, tengo dos máquinas virtuales Solaris 10 con solo dos o tres conjuntos de datos de muestra, pero lo mismo sucede en los grandes sistemas SPARC donde está destinado a funcionar, y hay muchos conjuntos de datos.

Relacionado:¿Cómo cambiar el shell cron (sh to bash)?

Respuesta aceptada:

SSH podría estar leyendo desde la entrada estándar, consumiendo su lista de acciones. Intente redirigir la entrada estándar de ssh a /dev/null:

ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER} </dev/null

Como regla general, cuando se ejecutan comandos que pueden interferir con la entrada estándar bajo un while read bucle de estilo, me gusta envolver todo el cuerpo del bucle en llaves:

cat /tmp/uuoc | while read RMT_FILESYSTEM ISMOUNTED
do {
    echo ${RMT_FILESYSTEM}@${MARKER}
    [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
    echo Remote Command Return Code: $?
} < /dev/null; done

Linux
  1. ¿Carácter especial '#' en el comando Perl Ssh?

  2. ¿Oring con True en un comando sobre Ssh?

  3. ¿Ssh a múltiples hosts y ejecutar un comando?

  4. Ejemplos de ciclos for y while de Bash

  5. linux ejecutar comando de forma remota

Golpear mientras se repite

Comando SSH

Cómo pasar la contraseña al comando SSH en Linux

El bucle while en los scripts de Shell

Haciendo un comando de larga ejecución en ssh

Cómo detener/prevenir la fuerza bruta SSH