web-dev-qa-db-fra.com

Script shell pendant que la ligne de lecture s'arrête après la première ligne

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.

83
bcbishop

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.

149
dogbane

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
5
jacobm654321

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
2
tripleee