Finalmente he logrado reducir un problema con el que he estado luchando durante algunas semanas. Utilizo SSH con "claves autorizadas" para ejecutar comandos de forma remota. Todo está bien, excepto cuando lo hago en un ciclo 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 destila de una implementación más grande que toma instantáneas y las replica entre los nodos en 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 zfs list "-H").
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 llamado similar a
POOL / zones / app1zone
POOL / zones / group2 / app2zone
etc.
El bucle anterior debe 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.
Se puede confirmar fácilmente que el programa encuentra el número correcto de conjuntos de datos al verificar el archivo "/ tmp / actionlist" después de que exista el script.
Si el comando ssh es reemplazado por, por ejemplo, un comando echo, entonces el ciclo itera a través de todas las líneas de entrada. O mi favorito: anteponer "echo" al comando ofensivo.
Si uso 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 comandos expandida.
¡Ahora estoy 99.999% seguro de que solo los 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 bucle while se perdieran repentinamente ... Si las primeras líneas de entrada no ejecutan un comando ssh, el bucle 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 unos dos o tres conjuntos de datos de muestra, pero lo mismo está sucediendo en los grandes sistemas SPARC en los que está destinado a funcionar, y hay muchos conjuntos de datos.
fuente
actionlist
. Intente redirigir la entrada estándar de ssh a/dev/null
Respuestas:
SSH podría estar leyendo de la entrada estándar, consumiendo su lista de acciones. Intente redirigir la entrada estándar de ssh a / dev / null:
Como regla general, cuando ejecuto comandos que pueden interferir con la entrada estándar bajo un
while read
bucle de estilo, me gusta envolver todo el cuerpo del bucle entre llaves:fuente
( </tmp/file [ -z "$SOMEVAR" ] && awk '{print "X", $0}' )
difiere igual con las llaves. Me refiero a la producción producida, no al hecho de que la llave de cierre debe estar en una nueva línea ...-n
opción que hace que (efectivamente) vuelva a abrir su stdin desde / dev / null.sudo
con el comando dentro del bucle?