Tengo el siguiente script de shell. El propósito es recorrer cada línea del archivo de destino (cuya ruta es el parámetro de entrada al script) y trabajar en cada línea. Ahora, parece que solo funciona con la primera línea en el archivo de destino y se detiene después de que esa línea se procesó. ¿Hay algún problema con mi guión?
#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets
FILENAME=$1
count=0
echo "proceed with $FILENAME"
while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME
echo "\ntotal $count targets"
En do_work.sh
, ejecuto un par de ssh
comandos.
bash
shell
ssh
while-loop
bcbishop
fuente
fuente
source
y simplemente salir oexec
. Pero este código no parece genuino, el OP notaría que el eco requiere-e
mostrar el avance de línea correctamente ...do_work.sh
Corressh
por casualidad?do_work.sh
origen y también ejecutardo.sh
conset -x
depurar.Respuestas:
El problema es que
do_work.sh
ejecutassh
comandos y por defectossh
lee desde stdin, que es su archivo de entrada. Como resultado, solo verá la primera línea procesada, porquessh
consume el resto del archivo y su ciclo while termina.Para evitar esto, pase la
-n
opción a sussh
comando para que se lea desde en/dev/null
lugar de stdin.fuente
cat
. Uno pensaría que un roedor en particular desconfiaría de esto.while read host ; do $host do_something ; done < /etc/hosts
lo evitaría. Eso es un gran salvavidas, ¡gracias!httpie
es otro comando que lee STDIN por defecto, y sufrirá el mismo comportamiento cuando sea llamado dentro de un bucle bash o fish. Usehttp --ignore-stdin
o configure la entrada estándar/dev/null
como arriba.De manera más general, una solución alternativa que no es específica
ssh
es redirigir la entrada estándar para cualquier comando que de otro modo consumiría lawhile
entrada del bucle.La adición de
</dev/null
es el punto crucial aquí (aunque las comillas corregidas también son algo importantes; vea también ¿ Cuándo ajustar las comillas alrededor de una variable de shell? ). Querrá usarlo aread -r
menos que requiera específicamente el comportamiento heredado ligeramente extraño que tiene sin él-r
.Otra solución alternativa que es algo específica
ssh
es asegurarse de que cualquierssh
comando tenga su entrada estándar atada, por ejemplo, cambiandoen su lugar, leer los comandos de un documento aquí, que convenientemente (para este escenario en particular) ata la entrada estándar de
ssh
para los comandos:fuente
La opción ssh -n evita verificar el estado de salida de ssh cuando se usa HEREdoc mientras se canaliza la salida a otro programa. Por lo tanto, se prefiere el uso de / dev / null como stdin.
fuente
<<EOF
anula la</dev/null
redirección. La<<
redirección después de ladone
es incorrecta.Esto me estaba sucediendo porque tenía
set -e
y ungrep
bucle en un bucle regresaba sin salida (lo que da un código de error distinto de cero).fuente