Shellprogrammieren: Integer Expression Expected

sh0x

Erfahrenes Mitglied
Hallo Leute,

ich habe mich ans Shellprogrammieren rangewagt und will einfach nur, dass mein Linuxserver nach 10 Minuten herunterfährt.

Code:
if [ `uptime | awk '{ print $3 }'` -gt 10 ] ; then
shutdown -h now
fi

funktioniert leider nicht. Bekomme immer den Fehler "integer expression expected".
Ich vermute nun, dass awk aus dem uptime einen String zurückgibt. Wie wandle ich das in einen Integer um, damit ich den Vergleich darauf anwenden kann?

Hat jemand eine Idee?
Danke für Unterstützung, ich werd noch wahnsinnig ;)

LG,
sh0x
 
funktioniert leider nicht. Bekomme immer den Fehler "integer expression expected".

Deine denke is schon richtig...
Der Fehler liegt darin das wenn der Rechner länger als 59 min oben ist,
steht da nimmer sowas wie 10 sondern steht dann an Position $3 sowas
wie z.B. 1:32, Und das ist kein Integer...
Aber da dein Rechner eh nur 10 min an ist sollte es eigentlich funktionieren.

Gruß

RedWing
 
Hi.

Also bei mir mogelt er da auch immer noch ein Komma dazu:
Code:
$ uptime | awk '{print $3}'
10,
D.h. auch wenn der Rechner noch keine Stunde läuft kommt das leider nicht hin.

Wie wäre es denn damit:
Code:
_uptime( ) {
    local IFS=$' \t,\n'

    uptime | ( read ign ign u ign; echo $(( ${u%:*}*60+${u#*:} )) )

}
 
Nee, so einfach geht's auch nicht...

Moment mal.

/edit: Heureka! ;)

Code:
_uptime( ) {
    local IFS=$' \t,\n'

    uptime | ( read ign ign u ign; echo $(( ${u/*:*/${u%:*}*60+${u#*:}} )) )
}

Achso, die Funktion gibt übrigens die Uptime in Minuten zurück.

Code:
if [ $(_uptime) -gt 10 ]; then
  shutdown 
fi

/edit: Heute beim Autofahren ist mir noch eine Vereinfachung eingefallen:
Code:
uptime | ( read ign ign u ign; echo $(( ${u/:/*60+} )) )
Gruß
 
Zuletzt bearbeitet:
Boah! ;-) kannst du mir diesen Code vielleicht mal näher erklären? Ich habe garkeine Ahnung, wie das funktioniert.
Ist das normale Shellprogrammierung oder haste das anderweitige Tricks reingebracht?
 
Hi.

Also das ist ganz normale (Bash) Shell-Programmierung ohne externe Tools wie awk oder sed.

Also ich erstelle ein Funktion namens _uptime (soviel ist ja klar denke ich). In der Funktion setze ich erstmal lokal die spezielle Shell-Variable IFS auf einen anderen Wert. Diese Variable enthält alle Zeichen die von der SHELL als Trennzeichen zwischen Worten erkannt werden. Da hab ich zu den sonstigen Zeichen jetzt nur noch ein Komma dazugeschummelt.

Das Dollarzeichen hab ich vor das Anführungszeichen geschrieben damit die Shell innerhalb der Anführungszeichen die mit Backslash versehenen Zeichen auch interpretiert.

Die Ausgabe des Kommandos uptime gebe ich mittels einer Pipe an eine Subshell (erkennbar durch die runden Klammern).

In der Subshell wird erstmal die Eingabe durch den read (Shell-) Befehl eingelesen und an Variablen zugewiesen; wobei die Zeile durch die Zeichen in der Shellvariable IFS in Worte zerhackstückt wird. Die Trennzeichen (also auch das Komma) werden weggeworfen.

Von den ganzen Worten auf der Zeile interessiert mich ja nur das dritte, dessen Wert in der Variable u gespeichert wird. Die restlichen Worte werden jeweils an die Variable ign (für ignore) zugewiesen.

Jezt hab ich also das dritte Wort in der Variable u. Jetzt muß ich nur noch die Stunden herausfinden mit 60 multiplizieren, zu den Minuten addieren und ausgeben.

Für's Rechnen gibts die arithmetische Expansion: $(( ... ))

Und dann gibt's da noch die ganz normale Variablen Expansion mit Ersetzung: ${var/pattern/string}. Hier wird der Wert der Variablen expandiert, dann die größte Übereinstimmung mit dem Pattern durch den String ersetzt.

Z.B. wenn das dritte Wort (bzw. der Wert der Variablen u) "3:05" ist, dann ist das Ergebnis des Ausdrucks ${u/:/*60+} gleich "3*60+05". Der Doppelpunkt wurde also einfach durch den String "*60+" ersetzt. Ist kein Doppelpunkt vorhanden, dann wird auch nichts ersetzt und der Wert bleibt unverändert.

Wie auch immer wird der Ausdruck dann noch arithmetisch ausgewertet und ausgegeben.

Wenn du mehr wissen willst, schau dir die Bash Manual page an und/oder den
Advanced Bash-Scripting Guide

Gruß
 
Ich versteh nicht, warum ein einfaches `shutdown -h -t 600` nicht reicht. Oder ein `shutdown -h <ZeitInZehnMinuten>`... Ist alles schick in der Manpage beschrieben.. ;)

3.
 
Hi.

Na ja, es ging ja nicht darum den Rechner in 10 min runterfahren zu lassen, sondern dafür zu sorgen (warum auch immer) das der Rechner wenn er mehr als 10 min an ist, runterfährt. Dazu muß man schon irgendwie die uptime auslesen und auswerten. Außer man führt den shutdown Befehl direkt nach dem Rechnerstart aus - allerdings wäre das auch nicht das Gleiche, da man den Shutdown mit dem Skript halt auch irgendwann später (immer in Abhängigkeit zur uptime) anstoßen könnte.

Gruß
 
deepthroat hat gesagt.:
Hi.

Na ja, es ging ja nicht darum den Rechner in 10 min runterfahren zu lassen, sondern dafür zu sorgen (warum auch immer) das der Rechner wenn er mehr als 10 min an ist, runterfährt. Dazu muß man schon irgendwie die uptime auslesen und auswerten. Außer man führt den shutdown Befehl direkt nach dem Rechnerstart aus - allerdings wäre das auch nicht das Gleiche, da man den Shutdown mit dem Skript halt auch irgendwann später (immer in Abhängigkeit zur uptime) anstoßen könnte.

Gruß


Genau, du verstehst mich richtig :)
Und habe es jetzt ja auch hinbekommen. Also nochmal vielen Dank an alle Beteiligten!
Ach übrigens: Wo hast du Shellprogrammieren so gut gelernt? Kannst du nen Howto oder so empfehlen? Gruß sh0x
 
Ui, jetzt soll ich wohl aus dem Nähkästchen plaudern?! ;-)

Also einerseits hab ich einige Sachen geschrieben (meist um irgendwelche Sachen aus dem Netz runterzuladen - mit Hilfe von externen Tools wie wget bzw. curl, sed, awk) wobei ich zumeist nur die Bash Manpage zu Hilfe genommen habe.

Dann hab ich auch einige Dateien die von anderen Leuten geschrieben wurden angeschaut, daran Änderungen vorgenommen und einfach verschiedene Anpassungen an den Profildateien gemacht.

Nicht zuletzt aber benutze ich die Bash natürlich (fast) täglich. An der Uni ist leider die [t]csh voreingestellt und das läßt sich leider auch nicht ändern. Da hab ich mir eine spezielle .login Datei für die (t)csh geschrieben so das automatisch Bash statt der Originallogin-Shell gestartet wird.

Empfehlen kann ich dir Working more productively with bash 2.x/3.x um deine Bash deinen Bedürfnissen anzupassen.

Gruß
 
Zurück