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 sshcomandos.
bash
shell
ssh
while-loop
bcbishop
fuente
fuente

sourcey simplemente salir oexec. Pero este código no parece genuino, el OP notaría que el eco requiere-emostrar el avance de línea correctamente ...do_work.shCorresshpor casualidad?do_work.shorigen y también ejecutardo.shconset -xdepurar.Respuestas:
El problema es que
do_work.shejecutasshcomandos y por defectosshlee desde stdin, que es su archivo de entrada. Como resultado, solo verá la primera línea procesada, porquesshconsume el resto del archivo y su ciclo while termina.Para evitar esto, pase la
-nopción a susshcomando para que se lea desde en/dev/nulllugar 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/hostslo evitaría. Eso es un gran salvavidas, ¡gracias!httpiees otro comando que lee STDIN por defecto, y sufrirá el mismo comportamiento cuando sea llamado dentro de un bucle bash o fish. Usehttp --ignore-stdino configure la entrada estándar/dev/nullcomo arriba.De manera más general, una solución alternativa que no es específica
sshes redirigir la entrada estándar para cualquier comando que de otro modo consumiría lawhileentrada del bucle.La adición de
</dev/nulles 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 -rmenos que requiera específicamente el comportamiento heredado ligeramente extraño que tiene sin él-r.Otra solución alternativa que es algo específica
sshes asegurarse de que cualquiersshcomando 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
sshpara 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
<<EOFanula la</dev/nullredirección. La<<redirección después de ladonees incorrecta.Esto me estaba sucediendo porque tenía
set -ey ungrepbucle en un bucle regresaba sin salida (lo que da un código de error distinto de cero).fuente