Script Shell tout en ligne de lecture de la boucle s'arrête après la première ligne
J'ai le script suivant. Le but est de boucler à travers chaque ligne du fichier cible (dont le chemin est le paramètre d'entrée pour le script) et de faire du travail à l'encontre de chaque ligne. Maintenant, il semble que seul le travail avec la première ligne du fichier cible et s'arrête au bout de cette ligne a obtenu traitées. Il n'y a rien de mal avec mon script?
#!/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"
Dans do_work.sh
, je lance un couple de ssh
commandes.
- Vous êtes sûr que c'est exactement le code que s'arrête après la première ligne?
- Votre script est bien, mais il y a peut être quelque chose de mal avec l'do_work.sh
- Oui, il peut manger jusqu'à l'entrée de tous, ou il peut être invoquée comme
source
et simplement la sortie ouexec
. Mais ce code n'a pas l'air authentique, l'OP remarquez que l'écho nécessite-e
pour afficher la ligne de nourrir correctement... - Ne
do_work.sh
exécuterssh
par hasard? - oui, do_work.sh exécute un couple ssh commandes. rien de spécial à ce sujet?
- Mieux vous montrer la
do_work.sh
source et de les exécuterdo.sh
avecset -x
à déboguer.
Vous devez vous connecter pour publier un commentaire.
Le problème est que
do_work.sh
s'exécutessh
commandes et par défautssh
lit l'entrée standard stdin qui est de votre fichier d'entrée. En conséquence, seule la première ligne de traités, parce quessh
consomme le reste du fichier, et votre boucle while se termine.Pour éviter cela, passer le
-n
option pour votressh
de commande pour le faire lire à partir de/dev/null
au lieu de stdin.cat
. Vous pourriez penser qu'un rongeur en particulier se méfier de cette.while read host ; do $host do_something ; done < /etc/hosts
permettrait de l'éviter. C'est tout à fait un épargnant de vie, merci!httpie
est une autre commande qui lit l'entrée standard STDIN par défaut, et il en souffrira le même comportement lorsqu'il est appelé à l'intérieur d'un bash ou de poisson boucle. Utilisationhttp --ignore-stdin
ou un ensemble standard d'entrée de/dev/null
comme ci-dessus.ssh -n option empêche la vérification de l'état de sortie de ssh lors de l'utilisation de HEREdoc tandis que la tuyauterie de sortie d'un autre programme.
Afin que l'utilisation de /dev/null comme stdin est préféré.
<<EOF
remplace la</dev/null
de redirection. Le<<
de redirection après ladone
est faux.Plus généralement, une solution de contournement qui n'est pas spécifique à
ssh
est la redirection de l'entrée standard d'une commande qui, autrement, consommer de lawhile
de la boucle d'entrée.L'ajout de
</dev/null
est le point crucial ici (même si le corrigé citant est également assez important; voir aussi Quand à envelopper des guillemets autour d'une variable d'environnement?). Vous souhaitez utiliserread -r
, sauf si vous avez expressément demander à l'héritage un peu étrange comportement que vous obtenez sans-r
.Une autre solution de toutes sortes qui est un peu spécifique à
ssh
est de s'assurer que toutssh
commande a son entrée standard lié, par exemple en changeantau lieu de lire les commandes à partir d'un document ici, idéalement (pour ce scénario particulier) relie l'entrée standard de
ssh
pour les commandes: