J'ai le script shell suivant. Le but est de faire une boucle sur chaque ligne du fichier cible (dont le chemin est le paramètre d’entrée du script) et de travailler sur chaque ligne. Maintenant, il semble ne fonctionner qu'avec la toute première ligne du fichier cible et s'arrête après le traitement de cette ligne. Y a-t-il un problème 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 deux commandes ssh
.
Le problème est que do_work.sh
exécute ssh
commandes et par défaut ssh
lit à partir de stdin qui est votre fichier d’entrée. En conséquence, vous ne voyez que la première ligne traitée, car ssh
consomme le reste du fichier et votre boucle while se termine.
Pour éviter cela, passez le -n
option sur votre commande ssh
pour la lire à partir de /dev/null
au lieu de stdin.
l'option ssh -n empêche la vérification du statut de sortie de ssh lors de l'utilisation de HEREdoc lors du transfert de la sortie vers un autre programme. Donc, l’utilisation de/dev/null en tant que stdin est préférable.
#!/bin/bash
while read ONELINE ; do
ssh ubuntu@Host_xyz </dev/null <<EOF 2>&1 | filter_pgm
echo "Hi, $ONELINE. You come here often?"
process_response_pgm
EOF
if [ ${PIPESTATUS[0]} -ne 0 ] ; then
echo "aborting loop"
exit ${PIPESTATUS[0]}
fi
done << input_list.txt
Plus généralement, une solution de contournement qui n'est pas spécifique à ssh
consiste à rediriger l'entrée standard de toute commande susceptible sinon de consommer l'entrée de la boucle while
.
while read -r LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh "$LINE" </dev/null
done < "$FILENAME"
L'addition de </dev/null
_ est le point crucial ici (bien que la citation corrigée soit aussi un peu importante; voir aussi Quand entourer des citations autour d’une variable Shell? ). Vous voudrez utiliser read -r
à moins que vous ne souhaitiez spécifiquement le comportement légèrement étrange hérité que vous obtenez sans -r
.
Une autre solution de contournement qui est quelque peu spécifique à ssh
consiste à s’assurer que toute commande ssh
a son entrée standard liée, par exemple. en changeant
ssh otherhost some commands here
pour lire les commandes d'un document here, ce qui lie commodément (pour ce scénario particulier) l'entrée standard de ssh
pour les commandes:
ssh otherhost <<'____HERE'
some commands here
____HERE