#1 Le 11/06/2008, à 17:48
- B@rtounet
SSH dans un script bash problème de boucle
Bonjour,
je suis confronté à un problème simple...
Soit un script qui ressemble à ca (ce n'est pas le meme mais c'est pour comprendre le principe)
sur le noeud 192.168.1.1
#!/bin/bash
hostname=$hostname
peernode="192.168.1.2"
echo on $hostname
ifconfig
ssh $peernode test.sh
et sur le noeud 192.168.1.2
#!/bin/bash
hostname=$hostname
peernode="192.168.1.1"
echo on $hostname
ifconfig
ssh $peernode test.sh
vous vous doutez bien que quand j'execute le script sur l'un ca tourne en boucle puisque l'un appel toujours l'autre à la fin du script
Je cherche un moyen d'arreter le script juste après la réponse sur server 2 sans tourner en boucle
Comment eviter de faire tourner en boucle un script qui appelle le meme script en ssh sur le noeud distant ??
Dernière modification par B@rtounet (Le 11/06/2008, à 17:49)
Hors ligne
#2 Le 11/06/2008, à 18:27
- Rude Wolf
Re : SSH dans un script bash problème de boucle
Une simple idée vite fait:
Tu crées un compteur, initialisé à 0 disons, et qui s'incrémente à chaque éxécution du script. Pour terminer la boucle, tu effectues un test de la valeur prise par le compteur et provoques l'arrêt du script lorsque cette valeur atteint 1 ou 2 (selon la position du test relativement à l'instruction ifconfig, et à l'instruction d'incrément).
Cordialement.
http://www.linux-pour-lesnuls.com/bash.php#tests
Hors ligne
#3 Le 11/06/2008, à 22:13
- B@rtounet
Re : SSH dans un script bash problème de boucle
il va passer à 0 tout le temps puisqu'a chaque ssh $peernode test.sh c'est le même script qui s'execute de zero sur le deuxieme noeud
Hors ligne
#4 Le 11/06/2008, à 22:19
- Totor
Re : SSH dans un script bash problème de boucle
Regarde au niveau des variables d'environnement.
Lorsque tu te connectes en SSH, des variables sont créées et valorisées.
Dans ton script, il faut tester la présence de telles variables. si c'est le cas c'est que tu es déjà en SSH et donc, tu appelles te reconnectes en passant une variable à ton script qui t'indique que le lancement du script provient d'une session déjà en SSH. En conséquence, la première chose à faire c'est de tester la présence de cette variable qui sert de flag.
-- Lucid Lynx --
Hors ligne
#5 Le 11/06/2008, à 22:36
- B@rtounet
Re : SSH dans un script bash problème de boucle
merci pour ta réponse, mais j'ai du mal à comprendre... peux tu etre plus clair ou me faire un exemple ?
Hors ligne
#6 Le 11/06/2008, à 23:12
- lolobu
Re : SSH dans un script bash problème de boucle
Une fois que tu es connecté après un ssh, les variables d'environnement $SSH_CLIENT, $SSH_CONNECTION et $SSH_TTY (à priori) sont définies et pas avant (vérifie tout de meme avec la commande env avec et sans ssh pour voir si c'est bien ca).
Donc si tu fais un test
if [ -n "$SSH_CLIENT" ] ; then
echo "Je fais ici ce que je veux faire si deja 1 ssh"
fi
Ou l'inverser
if [ -z "$SSH_CLIENT" ] ; then
echo "Je vais ici ce que je veux faire si pas de ssh"
fi
Hors ligne
#7 Le 11/06/2008, à 23:40
- B@rtounet
Re : SSH dans un script bash problème de boucle
Oui mais je pense pas que cela règle mon problème, car ce que je souhaite c'est juste avoir le résultat de la commande ssh $peernode .test.sh
De plus ces variables d'environnement seront toujours définies, car c'est un cluster ou de nombreux scripts font en permanence des connexion ssh.
De plus meme en définissant ces variables ca n'empechere pas de tourner en boucle puisque que je veux appeler en fin de script une commande ssh sur l'autre noeud
Hors ligne
#8 Le 12/06/2008, à 14:08
- Totor
Re : SSH dans un script bash problème de boucle
Si j'ai bien compris, je pense que tu peux t'en sortir très facilement :
Sur tes 2 nodes, tu fais 2 scripts :
Sur le node 1:
lanceur.sh
#!/bin/bash
export EXE_LOCALE=1
./test.sh
test.sh
#!/bin/bash
hostname=$hostname
peernode="192.168.1.2"
echo on $hostname
ifconfig
[ ${EXE_LOCALE} -eq 1 ] && ssh $peernode test.sh
Sur le node 2:
lanceur.sh
#!/bin/bash
export EXE_LOCALE=1
test.sh
test.sh
#!/bin/bash
hostname=$hostname
peernode="192.168.1.1"
echo on $hostname
ifconfig
[ ${EXE_LOCALE} -eq 1 ] && ssh $peernode test.sh
et tu lances le script lanceur.sh en point de départ sur l'un ou l'autre des nodes.
La variable EXE_LOCALE te permet ainsi de savoir si le lancement du script est local ou non.
Tiens, je pense même à une autre solution :
Le premier appelle au script test.sh s'effectue en donnant une valeur particulière à un paramètre d'entrée.
Ensuite, dans ton script, tu spécifies une valeur différentes pour les autres appelles. Ce qui donne :
1er appelle :
./test.sh 0
et tes scripts test.sh :
#!/bin/bash
hostname=$hostname
peernode="192.168.1.2"
echo on $hostname
ifconfig
[ $1 -eq 0 ] && ssh $peernode test.sh 1
et
#!/bin/bash
hostname=$hostname
peernode="192.168.1.1"
echo on $hostname
ifconfig
[ $1 -eq 0 ] && ssh $peernode test.sh 1
-- Lucid Lynx --
Hors ligne
#9 Le 12/06/2008, à 18:26
- B@rtounet
Re : SSH dans un script bash problème de boucle
Merci pour ta réponse très précieuse, c'est en effet, sur la deuxieme option que j'étais partis... car je veux faire ca en un seul script sur chaque noeud, sans lanceur..
Le probleme c'est que faut que j'adate cela sur le vrai script que j'ai mis en place... et là c'est pas de la tarte, car tu te doute bien que c'etait pas sur ce script si simple que je voulais travailler mais sur un autre...
Et bien sur le vrai script à des arguments deja un peu partout donc ca va etre chaud...
voici le vrai script si ca t'interesse.... c'est autre chose...
#!/bin/bash
#DOMLIST V1.0
#Antony MARTINEAU
#Xen Virtual Machine Information by Antony MARTINEAU.
test -x
ramdisk="/tmpramfs"
if [ -z $(mount | grep /tmpramfs | awk '{print $3}') ]; then
if [ -z $(ls / | grep tmpramfs) ]; then
mkdir /tmpramfs
mount -t tmpfs -o size=16M, tmpfs /tmpramfs > /dev/null 2>&1
else
mount -t tmpfs -o size=16M, tmpfs /tmpramfs > /dev/null 2>&1
fi
fi
#Fonction pour afficher les echo en couleur
#31=rouge, 32=vert, 33=jaune,34=bleu, 35=rose, 36=cyan, 37= blanc
color()
{
printf '\033[%sm%s\033[m\n' "$@"
}
xmlist="$ramdisk/xmlistfic"
xmsched="$ramdisk/schedlist"
xmlv="$ramdisk/lvdisp"
psaux="$ramdisk/psaux"
dompath="/etc/xen/vm"
xmuptime="$ramdisk/xmuptimefic"
lsof="$ramdisk/lsof"
peernode=$(cat /etc/xen/peernode | grep name | cut -d" " -f2)
hostname=$(uname -n)
arg=$1
arg2=$2
################################HELP##################################
if [ "$arg" = "--help" ]; then
echo "domlist v1.0 by Antony MARTINEAU"
echo "Xen virtual machine informations"
echo "Usage: domlist DomU_name (ex: domlist lippi-web)"
echo "Without argument, all is default"
echo "option -g (gui) show list whithout column and backspace, separated by ;"
exit 0
fi
#####################################################################
if [ "$arg" != "all" ]; then
if [ "$2" != "all" ]; then
if [ ! -e $arg ]; then
if [ "$arg" = "-g" ]; then
domexist=$(cat $dompath/*|grep $2 |cut -d'"' -f2)
else
domexist=$(cat $dompath/*|grep $1 |cut -d'"' -f2)
fi
if [ -z $domexist ]; then
if [ "$arg" = "-g" ]; then
echo $2 does not exist
exit 0
else
echo $1 does not exist
exit 0
fi
fi
fi
fi
fi
######################################################################
tab1()
{
echo `color 31 "On $hostname"`
echo -e `color 32 "Name Status ID Uptime Vcpus Time Weight Cap State Memory Resources -size- -size- -size- -size- VNC-Port"` |gawk -F" " ' { printf("%-17s %-6s %-5s %-9s %-3s %-6s %-2s %-3s %-6s %-5s %-17s %-5s %-5s %-5s %-5s %s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) }'
}
tab2()
{
echo `color 31 "On $hostname"`
echo -e `color 32 "Name ;Status ;ID ;Uptime ;Vcpus ;Time ;Weight ;Cap ;State ;Memory ;Resources ;-size- ;-size- ;-size- ;-size- ;VNC-Port"` |gawk -F" " ' { printf("%-17s %-6s %-5s %-9s %-3s %-6s %-2s %-3s %-7s %-8s %-17s %-5s %-5s %-5s %-5s %s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) }' | sed -e 's/ //g'
}
if test -f $xmlist
then
rm -f $xmlist
fi
if test -f $xmsched
then
rm -f $xmsched
fi
if test -f $xmuptime
then
rm -f $xmuptimefic
fi
if test -f $xmlv
then
rm -f $xmlv
fi
if test -f $psaux
then
rm -f $psaux
fi
if test -f $lsof
then
rm -f $lsof
fi
xm list > $xmlist
xm sched-credit > $xmsched
xm uptime > $xmuptime
lvdisplay > $xmlv
ps aux > $psaux
lsof > $lsof
if [ "$arg" = "all" ]; then
arg=$empty
fi
if [ -z $arg ]; then
tab1
else
if [ "$arg" != "-g" ]; then
tab1
fi
fi
lines=$(cat $dompath/*|grep "name"|cut -d'"' -f2| wc -l)
if [ -z $lines ]; then
lines=1
fi
if [ -z $arg ]; then
vmnum=1
else
if [ "$arg" = "-g" ]; then
if [ "$2" = "all" ]; then
vmnum=1
echo mouhahaha
else
if [ -z $2 ]; then
echo pouet
vmnum=1
else
vmnum=$(cat /etc/xen/vm/* | grep "name" | awk '{print NR,$0}' | grep "$2" | awk '{print $1}')
lines="$vmnum"
fi
fi
else
vmnum=$(cat /etc/xen/vm/* | grep "name" | awk '{print NR,$0}' | grep "$1" | awk '{print $1}')
lines="$vmnum"
fi
fi
for i in `seq $vmnum $lines`
do
vmname[$i]=$(cat $dompath/*|grep "name" |cut -d'"' -f2 |sed -n "$i{p;q;}")
vname=${vmname[$i]}
pidvm=$(cat $psaux | grep -w qemu-dm |grep -w $vname | awk '{print $2}')
vmid=$(cat $xmlist | grep -w $vname | awk '{print $2}' | cut -d":" -f2)
vmcpu=$(cat $dompath/$vname | grep vcpus | cut -d"=" -f2)
vmstate=$(cat $xmlist | grep -w $vname | awk '{print $5}' | cut -d":" -f2)
vmtime=$empty
lvname=$(echo $res | sed 's/r/vm/')
vmexist=$(cat $xmlist | grep $vname | awk '{print $1}')
uptime=$empty
vmweigt=$empty
if [ ! -z $vmid ]; then
vmweight=$(cat $xmsched | grep -w $vname | awk '{print $3}' | cut -d":" -f2)
else
vmweight=$(cat $dompath/$vname | grep "cpu_weight" | cut -d"=" -f2)
fi
vmcap=$empty
if [ ! -z $vmid ]; then
vmcap=$(cat $xmsched | grep -w $vname | awk '{print $4}' | cut -d":" -f2)
else
vmcap=$(cat $dompath/$vname | grep cpu_cap | cut -d"=" -f2)
fi
second=$(cat $xmlist | grep -w $vname | awk '{print $6}' | cut -d":" -f2 | cut -d"." -f-1)
if [ -z $second ]; then #second est nulle
vmtime=""
else
if [ "$second" -lt 3600 ]; then
second=$(cat $xmlist | grep -w $vname | awk '{print $6}' | cut -d":" -f2 | cut -d"." -f-1)
vmtime=$(echo $second's')
else
min=$(($second/60))
if [ "$min" -lt 1440 ]; then
vmtime=$(echo $min'm')
else
hour=$(($min/60))
vmtime=$(echo $hour'h')
fi
fi
fi
day=$(cat $xmuptime | grep -w $vname | cut -d"," -f1|awk '{print $4}'| sed '/^$/d')
if [ ! -z $day ]; then #day est non nul
day=$(cat $xmuptime | grep -w $vname | awk '{print $3}')
hours=$(cat $xmuptime | grep -w $vname | cut -d":" -f1 | cut -d"," -f2 | sed 's/ //g')
if [ "$hours" -lt 10 ]; then
hours=$(cat $xmuptime | grep -w $vname | cut -d":" -f1 | cut -d"," -f2 | sed 's/ //g'| sed 's/^/0/g')
uptime=$(cat $xmuptime | grep $vname | awk '{print $3,$4,$5}'|cut -d":" -f2-3 | cut -d":" -f1)
uptime=$(echo $hours:$uptime |sed 's/^/'$day'd,/g'| sed 's/:/h:/2' | sed 's/$//')
else
uptime=$(cat $xmuptime | grep $vname | awk '{print $3,$4,$5}'|cut -d":" -f2-3 | cut -d":" -f1)
uptime=$(echo $hours:$uptime |sed 's/^/'$day'd,/g'| sed 's/:/h:/2' | sed 's/$//' )
fi
else #day est nul
hours=$(cat $xmuptime | grep -w $vname | cut -d"," -f1 | awk '{print $3}' | cut -d":" -f1)
#echo $hours
if [ -z $hours ]; then
uptime=$(cat $xmuptime | grep $vname | awk '{print $3,$4,$5}'| sed 's/^/'$day'd,/g' | cut -d":" -f1 | sed 's/:/h:/2' | sed 's/$/m/' )
else
if [ "$hours" -lt 10 ]; then
uptime=$(cat $xmuptime | grep -w $vname | cut -d"," -f1 | awk '{print $3}' | cut -d":" -f-2 | sed 's/^/0/' | sed 's/^//' )
else
uptime=$(cat $xmuptime | grep $vname | awk '{print $3,$4,$5}'| sed 's/$//'| cut -d":" -f-2 |sed 's/^//')
fi
fi
fi
vmresor=$(cat $dompath/* |grep -A28 $vname | grep "#_r" |cut -d'"' -f2 | cut -d"#" -f2 )
res4=$( echo $vmresor | cut -d"_" -f5)
res3=$( echo $vmresor | cut -d"_" -f4)
res2=$( echo $vmresor | cut -d"_" -f3)
res1=$( echo $vmresor | cut -d"_" -f2)
vmmem=$empty
if [ ! -z $vmid ]; then
if [ "$1" = "-g" ]; then
vmmem=$(cat $xmlist | grep -w $vname | awk '{print $3}' | cut -d":" -f2)
else
vmmem=$( cat $xmlist | grep -w $vname | awk '{print $3}' | cut -d":" -f2 |sed 's/$/MB/')
fi
else
if [ "$1" = "-g" ]; then
vmmem=$(cat /etc/xen/vm/lippi-web | grep memory | cut -d"=" -f2)
else
vmmem=$(cat $dompath/$vname | grep memory | cut -d"=" -f2 |sed 's/$/MB/')
fi
fi
sizer1=$empty
if [ ! -z $res1 ]; then
lv1=$(echo $res1 | sed 's/r/lv/')
sizer1=$(lvdisplay 2> /dev/null | grep -A8 -w $lv1 | grep "LV Size" | awk '{print $3,$4}' | sed 's/ //' | sed 's/.00//'| sed -n '1p')
else
res1=" "
fi
sizer2=$empty
if [ ! -z $res2 ]; then
lv2=$(echo $res2 | sed 's/r/lv/')
sizer2=$(lvdisplay 2> /dev/null | grep -A8 -w $lv2 | grep "LV Size" | awk '{print $3,$4}'| sed 's/ //'| sed 's/ //' | sed 's/.00//'| sed -n '1p')
else
res2=" "
fi
sizer3=$empty
if [ ! -z $res3 ]; then
lv3=$(echo $res3 | sed 's/r/lv/')
sizer3=$(lvdisplay 2> /dev/null | grep -A8 -w $lv3 | grep "LV Size" | awk '{print $3,$4}'| sed 's/ //'| sed 's/ //' | sed 's/.00//'| sed -n '1p')
else
res3=" "
fi
sizer4=$empty
if [ ! -z $res4 ]; then
lv4=$(echo $res4 | sed 's/r/lv/')
sizer4=$(lvdisplay 2> /dev/null | grep -A8 -w $lv4 | grep "LV Size" | awk '{print $3,$4}'| sed 's/ //'| sed 's/ //' | sed 's/.00//'| sed -n '1p')
else
res4=" "
fi
if [ -z $pidvm ]; then
vncport="No vnc"
else
vncport=$( cat $lsof | grep $pidvm | grep "TCP *" | awk '{print $8}' | cut -d":" -f2 )
fi
if [ -z $vmexist ]; then
vmrun="off"
else
vmrun="on"
fi
list1 ()
{
echo -e "$vname/$vmrun/$vmid/$uptime/$vmcpu/$vmtime/$vmweight/$vmcap/$vmstate/$vmmem/$res1 $res2 $res3 $res4/$sizer1/$sizer2/$sizer3/$sizer4/$vncport"
}
list2 ()
{
echo -e "$vname/;$vmrun/;$vmid/;$uptime/;$vmcpu/;$vmtime/;$vmweight/;$vmcap/;$vmstate/;$vmmem/;$res1 $res2 $res3 $res4/;$sizer1/;$sizer2/;$sizer3/;$sizer4/;$vncport;"
}
if [ -z $arg ]; then
list1
else
if [ "$arg" = "-g" ]; then
list2
else
list1
fi
fi
done |
if [ -z $arg ]; then
gawk -F"/" ' { printf("%-12s %-6s %-5s %-9s %-5s %-6s %-6s %-3s %-6s %-6s %-17s %-6s %-6s %-6s %-6s %-s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) }'
else
if [ "$arg" = "-g" ]; then
gawk -F"/" ' { printf("%-12s %-7s %-5s %-9s %-6s %-6s %-7s %-4s %-7s %-8s %-17s %-7s %-7s %-7s %-7s %-#s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) }' | sed -e 's/ //g'
else
gawk -F"/" ' { printf("%-12s %-6s %-5s %-9s %-5s %-6s %-6s %-3s %-6s %-6s %-17s %-6s %-6s %-6s %-6s %-s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) }'
fi
fi
ssh $peernode domlist $arg
Comme tu vois c'est pas la meme chose, il faut pas que le nouvel argument viennent interferer avec les autres...
Hors ligne
#10 Le 12/06/2008, à 22:07
- Totor
Re : SSH dans un script bash problème de boucle
lorsque mes scripts ont des paramètres optionnels, j'écris une fonction qui test en totalité tous les arguments et qui renseigne des variables suivant ce qu'elle trouve.
Si ça peut t'aider, voici à quoi ça ressemble :
#!/bin/sh
#set -x
LESS=0
SYS=0
OPT=""
FIC=""
SID=""
REP_SQL="sql/"
STRING="-S|-s|-l|-less|-sys"
export LESS SYS OPT FIC SID REP_SQL STRING
affiche_syntaxe()
{
echo "Syntaxe de la commande :"
echo "$0 -S <SID> -s|-l <FICHIER> [-less] [-sys]"
echo "\t -S : Indique le SID de la base"
echo "\t -s : Indique que <fichier> est un script sql se trouvant dans le sous-dossier 'sql'"
echo "\t -l : Indique que <fichier> est un fichier contenant le nom des scripts sql"
echo "\t -less : Affiche les logs sql"
echo "\t -sys : Indique que le script est à exécuter en tant que 'sys'"
}
verif_param()
{
var=1
while [ $var -le $# ]
do
# on récupere la valeur de la variable ayant l'indice $var
myvar=`eval echo \\$$var`
case $myvar in
"-less")
# l'option -less est précisée
LESS=1;;
"-sys")
# l'option -sys est précisée
SYS=1;;
"-s"|"-l")
# tests sur le fichier
if [ "$OPT" != "" ]; then
# option redondante !
return 1
fi
OPT=$myvar
if [ $var -eq $# ]; then
# le fichier n'est pas précisé
return 1
fi
# Le paramètre suivant doit être le nom du fichier
var=`expr $var + 1`
FIC=`eval echo \\$$var`
# on vérifie que la valeur de $FIC n'est pas un paramètre potentiel
ERR=`echo $FIC|egrep -e $STRING`
if [ "$ERR" != "" ]; then
return 1
fi
if [ "$OPT" == "-s" ]; then
FIC=$REP_SQL$FIC
fi
;;
"-S")
if [ "$SID" != "" ]; then
# option redondante !
return 1
fi
if [ $var -eq $# ]; then
# le SID n'est pas précisé
return 1
fi
# Le paramètre suivant doit être le SID
var=`expr $var + 1`
SID=`eval echo \\$$var`
# on vérifie que la valeur de $SID n'est pas un paramètre potentiel
ERR=`echo $SID|egrep -e $STRING`
if [ "$ERR" != "" ]; then
return 1
fi
esac
var=`expr $var + 1`
done
# si ni le SID ni le fichier n'est renseigné, c'est qu'il y a une erreur
if [ "$SID" = "" ] || [ "$FIC" = "" ]; then
return 1
fi
return 0
}
verif_param $*
if [ $? -ne 0 ]; then
affiche_syntaxe
exit 1
fi
-- Lucid Lynx --
Hors ligne