Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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 ? smile

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... hmm

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