oiooiooioiioooiioiioiooo
Goto Top

Bash Script contains Bilden und nutzen

Tach,
habe meinem Script ein paar contains verleihen wollen.
Irgend wie bekomme ich nun komische Ergebnisse:
nach dem Ich für die Zeile 17 die Zeile 16 aktiviere bekomme ich die Aussage: „1.VM konnte nicht gestartet werden!“ Dabei werden aber alle gestartet.
Wenn ich statt der Zeile 16 die 17 verwende, dann läuft alles richtig. Was genau könnte hier die Ursache sein?

#!/bin/sh

WTAG=`date +%a`
TAGZEIT=`date +%d.%m.%Y-%H:%M:%S`
DATUMZEIT=“$WTAG $TAGZEIT“
AUSGABEF=/tmp/ausgabe.txt
ZEITF=/tmp/zeit.txt
LOGTMP=/tmp/vmlogtmp.txt
LOGFILE=/root/vmlog.txt

case $1 in
        start)
                for i in $(virsh list --all | grep 'ausschalten' | awk -F " " '{print $2}')  
                         do
                                DOMSTART="Domain $i gestartet"  
#                               echo $DATUMZEIT > $ZEITF
                                echo `date +%a` `date +%d.%m.%Y-%H:%M:%S` > $ZEITF
                                virsh start $i > $AUSGABEF
                                sed -i '$d' $AUSGABEF  
                                cat $ZEITF $AUSGABEF >> $LOGFILE
                                cat $ZEITF $AUSGABEF > $LOGTMP
                                if [ `grep -i "$DOMSTART" $AUSGABEF | wc -l` != 1 ]  
                                then
                                echo "$i konnte nicht gestartet werden!"  
                                else
                                echo "Sart von $i erfolgreich"  
                                fi &
                        done
        ;;
        stop)
                for i in $(virsh list | grep laufend | awk -F " " '{print $2}')  
                        do
                                virsh shutdown $i &
                                if [ $? -eq 0 ]
                                then
                                echo $i wurde herruntergefahren alles ok!
                                else
                                echo $i kann nicht, nichts ist ok!
                                fi
                        done
        ;;
        *) echo "Please use start or stop."  
        ;;
esac

Grüße
Ich

Content-ID: 337215

Url: https://administrator.de/contentid/337215

Ausgedruckt am: 23.11.2024 um 16:11 Uhr

freeker
Lösung freeker 09.05.2017 um 17:24:40 Uhr
Goto Top
Hallo,

Schreibe mal in die 2. Zeile "set -x"

Das löst zwar nicht das Problem, aber damit siehst du was passiert. Das ist eine debugging Option.
BassFishFox
Lösung BassFishFox 09.05.2017 aktualisiert um 19:37:00 Uhr
Goto Top
Hallo,

In Zeile 5

DATUMZEIT=“$WTAG $TAGZEIT

sind das auf den Kopf gestellte " ? Tausch die gegen ` aus.

echo `date +%a" "%d.%m.%Y-%H:%M:%S`  

klappt uebrigens auch. face-wink


BFF
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 10.05.2017 aktualisiert um 14:21:42 Uhr
Goto Top
Vielen Dank euch beiden!

@freeker

das Debug habe ich total vergessen.

@BassFishFox

Variante 1 funktioniert nicht.
Variante 2 funktioniert und gefehlt mir viel mehr! Aber.

Das Ergebnis ist leider immer noch nicht wie gewünscht:

Mit dem oberem CODE der Zeile 16: echo $DATUMZEIT > $ZEITF

 bash -x ./vmstart.sh start
++ date '+%a %d.%m.%Y-%H:%M:%S'  
+ DATUMZEIT='Mi 10.05.2017-13:40:06'  
+ AUSGABEF=/tmp/ausgabe.txt
+ ZEITF=/tmp/zeit.txt
+ LOGTMP=/tmp/vmlogtmp.txt
+ LOGFILE=/root/vmlog.txt
+ case $1 in
++ virsh list --all
++ grep ausschalten
++ awk -F ' ' '{print $2}'  
+ for i in '$(virsh list --all | grep '\''ausschalten'\'' | awk -F " " '\''{print $2}'\'')'  
+ DOMSTART='Domain VM1 gestartet'  
+ echo Mi 10.05.2017-13:40:06
+ virsh start VM1
+ sed -i '$d' /tmp/ausgabe.txt  
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
+ for i in '$(virsh list --all | grep '\''ausschalten'\'' | awk -F " " '\''{print $2}'\'')'  
+ DOMSTART='Domain VM2 gestartet'  
+ echo Mi 10.05.2017-13:40:06
+ virsh start VM2
++ grep -i 'Domain VM1 gestartet' /tmp/ausgabe.txt  
++ wc -l
+ '[' 0 '!=' 1 ']'  
+ echo 'VM1 konnte nicht gestartet werden!'  
VM1 konnte nicht gestartet werden!
+ sed -i '$d' /tmp/ausgabe.txt  
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
[root@backupmain ~]# ++ grep -i 'Domain VM2 gestartet' /tmp/ausgabe.txt 
++ wc -l
+ '[' 1 '!=' 1 ']'  
+ echo 'Sart von VM2 erfolgreich'  
Sart von VM2 erfolgreich


Mit dem oberem CODE der Zeile 17: echo `date +%a` `date +%d.%m.%Y-%H:%M:%S` > $ZEITF

bash -x ./vmstart.sh start
++ date '+%a %d.%m.%Y-%H:%M:%S'  
+ DATUMZEIT='Mi 10.05.2017-13:46:26'  
+ AUSGABEF=/tmp/ausgabe.txt
+ ZEITF=/tmp/zeit.txt
+ LOGTMP=/tmp/vmlogtmp.txt
+ LOGFILE=/root/vmlog.txt
+ case $1 in
++ virsh list --all
++ grep ausschalten
++ awk -F ' ' '{print $2}'  
+ for i in '$(virsh list --all | grep '\''ausschalten'\'' | awk -F " " '\''{print $2}'\'')'  
+ DOMSTART='Domain VM1 gestartet'  
++ date +%a
++ date +%d.%m.%Y-%H:%M:%S
+ echo Mi 10.05.2017-13:46:26
+ virsh start VM1
+ sed -i '$d' /tmp/ausgabe.txt  
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
+ for i in '$(virsh list --all | grep '\''ausschalten'\'' | awk -F " " '\''{print $2}'\'')'  
+ DOMSTART='Domain VM2 gestartet'  
++ date +%a
++ grep -i 'Domain VM1 gestartet' /tmp/ausgabe.txt  
++ wc -l
++ date +%d.%m.%Y-%H:%M:%S
+ echo Mi 10.05.2017-13:46:26
+ '[' 1 '!=' 1 ']'  
+ virsh start VM2
+ echo 'Sart von VM1 erfolgreich'  
Sart von VM1 erfolgreich
+ sed -i '$d' /tmp/ausgabe.txt  
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
+ cat /tmp/zeit.txt /tmp/ausgabe.txt
[root@backupmain ~]# ++ grep -i 'Domain VM2 gestartet' /tmp/ausgabe.txt 
++ wc -l
+ '[' 1 '!=' 1 ']'  
+ echo 'Sart von VM2 erfolgreich'  
Sart von VM2 erfolgreich

EDIT: Kleine Anmerkung: Ich habe mir überlegt, dass der Script zu schnell die Aufgaben abarbeitet, und habe nach Zeile 15 "sleep 1" eingebaut.... Und es geht! Warum? oO
freeker
freeker 10.05.2017 um 15:52:00 Uhr
Goto Top
Hallo,

Deine Ausgabe sieht echt merkwürdig aus.
Der startet schon den 2. Durchlauf der Schleife bevor er vom 1. Durchgang die if-Anweisung prüft.
Mit Zeile 17 statt 16 hast du eine minimal höhere Druchlaufzeit, was ausreicht für die if-Abfrage. Daher geht es auch mit dem "sleep 1"

Das eigentliche Problem ist dadurch aber nicht behoben, sondern nur vertuscht.

Ich weiß leider nicht was für eine Distribution du benutzt. Das "#!/bin/sh" kann je nach Betriebssystem standartmäßig auf unterschiedliche Shells verweisen. Bei Fedora wird da "bash" ausgeführt und unter Ubuntu beispielsweise "dash". Prüfen kannst du das mit "ls -l /bin/sh".
Ich gebe in meinen Scripten immer direkt "#!/bin/bash" in Zeile 1 ein um sicher zu gehen.
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 10.05.2017 um 16:08:53 Uhr
Goto Top
Ausgabe egab: /bin/sh -> bash

Habe die zeile geändert in "#!/bin/bash"

Hilft nicht.

Verwendet wird CentOS 7 Linux version 3.10.0-514.16.1.el7.x86_64
freeker
Lösung freeker 10.05.2017 um 16:43:22 Uhr
Goto Top
Ich glaube ich habe den Übeltäter gefunden.

Zeile 27 das "&" hinter fi bewirkt, dass die if-Anweisung im Hintergrund ausgeführt wird und der Rest weiter läuft.
Weg damit.
BassFishFox
BassFishFox 10.05.2017 um 19:20:44 Uhr
Goto Top
Halloele,

In dem Zusammenhang wuerde ich das vorhandensein des "&" am Ende der Zeile 33 auch pruefen wollen.
Oder soll ds Kommando dort in den Hintergrund geschickt werden?

BFF
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 11.05.2017 um 09:31:13 Uhr
Goto Top
Guten Morgen,

@freeker

Ja das war es! Danke für die Aufklärung. Ich dachte es würde dafür sorgen, dass die Schleife wiederholt werden soll bis dies abgearbeitet ist. Jetzt habe ich die Logik auch verstanden.

Jetzt denke ich weiter und meine Befürchtung ist, wenn ich den Start der VM´s nicht in Hintergrund schiebe, und beim Start etwas hängen bleibt, die anderen z.B. 5 nicht welche nach der Problem Maschine auch nicht mehr starten. Oder Denke ich da falsch?

Ich Glaube die 1 Sec Sleep kann man verkraften.

@BassFishFox

Ja auch da muss ich es entfernen, aber unten war ich noch gar nicht, da muss ich jetzt eine Prüfung einbauen welche nach Shutdown prüffen soll, dass die VM 100% aus ist. Und ggf mich kontaktieren. Problem ist dabei, dass es teilweise um Windows Systeme handelt welche beim Herunterfahren ewig brauchen. Hinterher soll die Image gesichert werden, und wenn es nicht aus ist, könnte es böse folgen haben. Mit Ping kann ich es leider nicht lösen. Denn die Netzwerkkarte wird ja fast am Anfang an abgemeldet. Und während ich das schreibe, fehlt mir „virsh domstate $i“ ein.

Eigentlich müsste ich diese Anfrage jetzt Schließen, mach ich aber sehr ungern, es macht richtig Spaß mit euch. Vielen Dank für euer Wissen.

Viele Grüße

Ich
freeker
freeker 11.05.2017 um 12:01:55 Uhr
Goto Top
Sobald dein virsh start fertig ist, läuft das Script weiter und sollte alle anderen normal starten.
Nur wenn dieser Befehl hängen bleibt und nicht beendet, hast du ein Problem. Das ist dann aber vermutlich eh ein größeres.

Wir hatten in den letzten 4 Jahren damit keine Probleme.

Noch ein kleiner Tipp:
Falls die Images bei euch auch auf normalen HDDs liegen, kann eine Zeitverzögerung beim Starten durchaus Sinn machen. Wenn alle Maschinen im Abstand von einer Sekunde gestartet werden, rattert sich die arme Festplatte sonst tot.
Wir haben unsere Images auf einem Raid1 liegen und verzögern sogar um 45 Sekunden.

MFG
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 11.05.2017 aktualisiert um 14:18:40 Uhr
Goto Top
Vielen Dank für deinen Tip. Das ist wirklich sehr nützliche Info.

Bin hier bei einem anderem Problem hängen geblieben.

Die Untere Schleife soll nicht nur die VM´s ausschalten sondern auch den Shutdown überwachen. Da habe ich mir folgendes überlegt.

Nach ausführen des Shutdowns:

stop)
	for i in $(virsh list | grep laufend | awk -F " " '{print $2}')  
		do
			DOMOFF="Domain $i wird heruntergefahren"  
			sleep 1
			echo $DATUMZEIT > $ZEITF
			virsh shutdown $i > $AUSGABEF
			sed -i '$d' $AUSGABEF  
			cat $ZEITF $AUSGABEF >> $LOGFILE
			cat $ZEITF $AUSGABEF > $LOGTMP
			if [ `grep -i "$DOMOFF" $AUSGABEF | wc -l` != 1 ]  
			then
				echo "$i Kann nicht angehalten werden!"  
		else
			echo "$i Fährtrunter!"  
				for c in $(virsh list | grep laufend | awk -F " " '{print $2}')  
				do
				echo "Shutdown $c eingeleitet!"  
				done
		fi
			done

Soll geprüft werden, dass die einzelne Domain wirklich aus sind.

	sleep 1
		for i in $(virsh list | grep laufend | awk -F " " '{print $2}')  
			do
				while (virsh domstate $i | grep laufend | awk -F " " '{print $1}')  
				do
				sleep 1
				echo $EINESEC
				let EINESEC=$EINESEC+1
				done

	echo $i nicht mehr Online!

			done

Aber ich finde leider nichts dazu, dass ich die Abfrage an diese Stelle umkehre.
freeker
freeker 11.05.2017 um 16:01:47 Uhr
Goto Top
Hmmm...

Wenn ich dich richtig verstanden habe, suchst du "virsh list --all"
Das zeigt den Zustand aller VMs an.
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 11.05.2017 um 16:14:29 Uhr
Goto Top
nee der Script soll einzeln die VM prüfen ist es online oder offline. Wenn Virsh sagt nach der Abfrage "virsh domstate VM1" ausgeschaltet, dann soll er mit dem Kopiervorgang beginnen.

Grundsätzlich ist die Zeile mit dem While schon richtig, nur wenn der Status "laufend" von der Abfrage nicht mehr abgebildet wird, wird die Schleife nicht beendet.

Es schaut dann so aus:

 ./vmstart.sh stop
VM1 Fährtrunter!
nach 1 Sec VM1 noch online!
nach 1 Sec VM2 noch online!
VM2 Fährtrunter!
nach 1 Sec VM1 noch online!
nach 1 Sec VM2 noch online!
laufend
1
laufend
2
laufend
3
laufend
4
laufend
5
laufend
6
laufend
7
laufend
8
laufend
9
laufend
10
11
12
13
^C
freeker
freeker 11.05.2017 um 17:18:41 Uhr
Goto Top
Zeile 5:
"while [ virsh domstate $i | grep laufend | awk -F " " '{print $1}' ] "


Falls das Ganze für ein Backup Script ist, kannst du dir auch "virsh suspend" und "virsh resume" ansehen. Das geht schneller als Runterfahren und Starten. Unsere VMs haben auch teilweise nicht auf den Shutdown-Befehl reagiert.

Aber das ist natürlich nicht ganz so sauber.
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 12.05.2017 aktualisiert um 12:30:51 Uhr
Goto Top
Das funktioniert leider nicht. Das habe ich auch schon mal probiert.

./vmstart.sh: Zeile 70: [: Fehlende `]'  
awk: Fatal: Die Datei »]« kann nicht zum Lesen geöffnet werden (Datei oder Verzeichnis nicht gefunden)


suspend / resume hat zwei Nacteile. Die vm nie neu gestartet werden und Die laufende Prozesse, werden vor der Sicherung nicht abgeschlossen. Auch weiß ich nicht ob man dann die Image für andere Virtualesierungslösungen verwendet werden können.
freeker
freeker 12.05.2017 um 16:04:51 Uhr
Goto Top
Das stimmt!

Mein Code wird nicht richtig angezeigt.
while [ `virsh domstate TEST | grep running | awk -F " " '{print $1}'` ]  

Deshalb gibt es die code-Tags
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 12.05.2017 um 16:24:07 Uhr
Goto Top
Jetzt spuckt er zwar keinen Fehler mehr aus, macht aber nicht was es machen soll face-sad

[root@backupmain ~]# ./vmstart.sh stop
VM1 Fährtrunter!
nach 1 Sec VM1 noch online!
nach 1 Sec VM2 noch online!
VM2 Fährtrunter!
nach 1 Sec VM1 noch online!
nach 1 Sec VM2 noch online!
VM1 nicht mehr Online!
VM2 nicht mehr Online!
[root@backupmain ~]# virsh list --all
 Id    Name                           Status
----------------------------------------------------
 5     VM1                            laufend
 6     VM2                            laufend

[root@backupmain ~]#
freeker
freeker 12.05.2017 um 17:27:09 Uhr
Goto Top
Deine For-Schleife funktioniert auch nicht richtig.
Zeile3:
for i in `virsh list | grep laufend | awk -F " " '{print $2}'`   
OIOOIOOIOIIOOOIIOIIOIOOO
OIOOIOOIOIIOOOIIOIIOIOOO 13.05.2017 um 14:49:22 Uhr
Goto Top
Danke dir! :D Aber das war es nicht. Bin gerade extra auf Arbeit gefahren.

Das Problem ist. Bei dir wird der Status in Englisch angezeigt. Bei mir Deutsch :D

Ich habe trotzdem deine Zeile genommen, denn bei der von mir verwendeten hat die Ausgabe nicht gestimmt.

Danke dir! Kann man jetzt eigentlich das so einrichten, dass es nach z.B. 60 Sec eine Mail sendet? Also diesen Timer begrenzen?

So Schaut es jetzt aktuell noch bei mir aus:

……...
stop)
	for i in $(virsh list | grep laufend | awk -F " " '{print $2}')  
		do
			DOMOFF="Domain $i wird heruntergefahren"  
			sleep 1
			echo $DATUMZEIT > $ZEITF
			virsh shutdown $i > $AUSGABEF
			sed -i '$d' $AUSGABEF  
			cat $ZEITF $AUSGABEF >> $LOGFILE
			cat $ZEITF $AUSGABEF > $LOGTMP
			if [ `grep -i "$DOMOFF" $AUSGABEF | wc -l` != 1 ]  
			then
				echo "$i Kann nicht angehalten werden!"  
				for d in $(virsh list | grep laufend | awk -F " " '{print $2}')  
				do
				echo "nach 10 Sec $d noch online!"  
				done
			else
			echo "$i Fährtrunter!"  
				for c in $(virsh list | grep laufend | awk -F " " '{print $2}')  
				do
				echo "nach 1 Sec $c noch online!"  
				done
			fi
		done
sleep 1
	for i in `virsh list | grep laufend | awk -F " " '{print $2}'`  
		do
			while [ `virsh domstate $i | grep laufend | awk -F " " '{print $1}'` ]  
			do
			sleep 1
			echo $EINESEC
			let EINESEC=$EINESEC+1
			done
		echo $i nicht mehr Online!
		done
;;
……………….
freeker
freeker 15.05.2017 um 17:13:19 Uhr
Goto Top
Das müsste irgendwie so aussehen...

if [ $EINESEC -eq 60 ]
then
    mail.......
    nocheineanweisenung
    break
fi

Das "break" sollte seine while-Schleife abbrechen.