Warum läuft dieses Bash-Skript nicht korrekt??

Gast #7173154
Lesenswert?

Hallo!

Ich möchte die Ausführungsdauer eines Befehls messen und abhängig davon 
unterschiedliche Kommandos ausführen.

Habe folgendes Skript geschrieben:
1
#!/bin/bash
2

3
MINTIME=20
4

5
BEGIN=$(date +%s)
6

7
#COMMAND
8

9
END=$(date +%s)
10
DIFFERENCE=$(expr $END - $BEGIN)
11

12
if ["$DIFFERENCE" -gt "$MINTIME"]
13
then
14
    echo "Ausführung war lang genug."
15
else
16
    echo "Ausführung war zu kurz!"
17
fi


Ich weiß, dass DIFFERENCE korrekt berechnet wird und ein Wert in 
Sekunden ist.
Leider wird trotzdem immer der Befehl bei else ausgeführt. Warum???

Danke im Voraus!
Gast #7173286
Lesenswert?

Ben B. schrieb:
> LOL. Was für ein bescheuerter Parser wenn der mit sowas nicht
> klarkommt.

Besser mal ruhig sein wenn man keine Ahnung hat.
»[« ist ein eigenständiges Programm in ›/usr/bin‹
Also ›/usr/bin/[‹

Und Programmaufrufe trennt man nun mal von Parametern.
#7173346
Lesenswert?

Zeno schrieb:
> Weil Deine Berechnung
>
1
DIFFERENCE=$(expr $END - $BEGIN)
> so nicht richtig ist.

Doch, ist er. Das ist dasselbe wie Backticks (`), aber im Gegensatz zu 
Backticks kann man die $() verschachteln.

> So sollte es funktionieren:
>
1
DIFFERENCE=$(( $END - $BEGIN ))

Nur der Neugierde halber habe ich es nochmal ausprobiert, und genau wie 
erwartet führt das zu einem Syntaxfehler. Wenn ich ich recht entsinne, 
gab / gibt es eine Shell, die das so haben will, aber welche? Keine 
Ahnung.
Gast #7173371
Lesenswert?

(prx) A. K. schrieb:
> Onkel Ted schrieb:
>> Ist deine Pfadvariable kaputt oder wozu der absolute Pfad?
>
> Ausprobiert? In bash ist "time" intern und kann mit -f nichts anfangen.

Stimmt. Aber für absolute Pfade bin ich einfach zu tippfaul!

command time -f"%e" sleep 1
1.00

\time -f"%e" sleep 1
1.00


und in ZSH hätten wir noch

=time -f"%e" sleep 1
Gast #7173454
Lesenswert?

Zeno schrieb:
> Norbert schrieb:
>> ›[‹ ist ein Befehl (und zwar ›test‹
>>
>> ›[‹ möchte gerne von Leerzeichen umringt sein damit es funktioniert.
> Das habe ich übersehen.
Gewöhn dir an [[ ]] zu verwenden, das beseitigt noch ein paar andere 
Fallen in die man immer wieder tappt. [ will man nur noch wenn man 
kompatibel zu Altsystemen sein muss.
(Firma: Funkenflug Industries) #7173494
Lesenswert?

> In solchen Fällen rate ich immer zu einem Buch.
Tolle Sache, so ein Buch. Damit kann man sich im Sommer frische Luft 
zufächeln und im Winter heizt man damit, dann spart es Kohlen und ist 
besonders nachhaltig.

Ey mal ehrlich. Man braucht das Rad nicht ständig neu zu erfinden. Auch 
in Sachen (Script-)Programmiersprachen gibt es viele Räder, die seit 
gefühlten Jahrhunderten völlig problemlos rollen.
#7173508
Lesenswert?

Ben B. schrieb:
> Auch in Sachen (Script-)Programmiersprachen gibt es viele Räder, die
> seit gefühlten Jahrhunderten völlig problemlos rollen.

Also beispielsweise die über 4 Jahrzehnte alte Bourne-Shell sh aus Unix, 
deren grundlegende Syntax dir hier auf so den Zeiger geht?

Das dürfte eine der ältesten und erfolgreichsten 
Script-Programmiersprachen sein, die heute noch im Einsatz sind.

> Man braucht das Rad nicht ständig neu zu erfinden.

Die in Linux vmtl meistverwendete Bourne-Again-Shell bash, auf die sich 
das hier konkret bezieht, ist eine Weiterentwicklung davon, aber auch 
schon über 3 Jahrzehnte alt.
Gast #7173860
Lesenswert?

Ben B. schrieb:
> Ganz ehrlich, ich hab Unix und seinen Ziehsohn schon immer gehasst. In
> Rechenzentren war ich immer froh, daß ich nur Hardware und
> Energietechnik mache und nur äußerst selten an die Software dran musste.

Stockt das Projekt Sattelzugmaschinenwohnmobil eigentlich oder warum 
verbringst du noch immer soviel Zeit damit hier Unsinn zu verbreiten? ;)
#7195366
Lesenswert?

Zeno schrieb:
> Weil Deine Berechnung
>
1
DIFFERENCE=$(expr $END - $BEGIN)
> so nicht richtig ist.
> So sollte es funktionieren:
>
1
DIFFERENCE=$(( $END - $BEGIN ))

Andersrum. Es funktioniert nur mit expr immer korrekt, für arithmetic 
expansion kann je nach shell integer overflow falsches Ergebnis liefern.
1
$ echo $((9999999999 + 1))
2
1410065408
3
$ echo $((9999999999999999999 + 1))
4
-8446744073709551616
Gast #7195457
Lesenswert?

Auf eines sollte man vielleicht noch hinweisen:
1
#!/bin/bash
2
A=1
3
B=2
4
C=$( expr $A + $B )
5
D=$(( A + B ))
6
echo "$A $B $C $D"
7
# -> 1 2 3 3

Weil man bei C=… ein Programm ›expr‹ aufruft muss man die Parameter mit 
$x $y übergeben.
Bei D=… wird das Ganze direkt in der Bash abgearbeitet, da kann man sich 
die Dollars sparen.
Beide rechnen gleich gut aber nicht gleich schnell.

Auf einem 64Bit System ist jedoch bei etwas über 9 Trillionen (2^63-1 ; 
9223372036854775807) Schluss mit lustig. 2^63 da die Bash mit signed 
integers arbeitet. Wenn man da noch eins addiert wechselt das Ergebnis 
auf negativ 9 Trillionen.

Das ist aber für alle Belange hier im Forum ausreichend, da hier zumeist 
Erbsen gezählt werden. Da reicht der Zählbereich vollkommen aus. ;-)
#7195484
Lesenswert?

(prx) A. K. schrieb:
>
>
> Also beispielsweise die über 4 Jahrzehnte alte Bourne-Shell sh aus Unix,
> deren grundlegende Syntax dir hier auf so den Zeiger geht?
>
> Das dürfte eine der ältesten und erfolgreichsten
> Script-Programmiersprachen sein, die heute noch im Einsatz sind.
>
>
> Die in Linux vmtl meistverwendete Bourne-Again-Shell bash, auf die sich
> das hier konkret bezieht, ist eine Weiterentwicklung davon, aber auch
> schon über 3 Jahrzehnte alt.


Die bash ist keine Weiterentwicklung von sh - sondern wurde mit dem 
gnu-Project entwickelt und lehnt sich an die bourne-shell an

Weiterentwicklungen von sh sind eher die c-shell, die Tennet csh also 
die tcsh und die zsh.

Von allen diesen shells dürfte die im Linux verbreitete bash nicht die 
eleganteste sein.

Apple hat sich ja vor ein paar Jahren wieder von der bash getrennt und 
dies waren nicht nur Lizenz-Gründe.

Ich persönlich komme auf bsd-Maschinen  besser mit tcsh zurecht.
Aber das kann natürlich Geschmacksache sein.

Allerdings finde ich, dass es nichts Schlimmeres gibt als Linux-Jünger 
die dann zu BSD wechseln und als erstes die System-shell auf bash 
umstellen wollen - und dann vielleicht noch so dreist sind und statt vim 
ihren komischen Nano nutzen wollen ;-)
#7195567
Lesenswert?

Norbert schrieb:
> Auf einem 64Bit System ist jedoch bei etwas über 9 Trillionen (2^63-1 ;
> 9223372036854775807) Schluss mit lustig. 2^63 da die Bash mit signed
> integers arbeitet. Wenn man da noch eins addiert wechselt das Ergebnis
> auf negativ 9 Trillionen.
> Das ist aber für alle Belange hier im Forum ausreichend, da hier zumeist
> Erbsen gezählt werden. Da reicht der Zählbereich vollkommen aus. ;-)

Das hat mit dem 64-bit System nichts zu tun, das ist abhängig von der 
Shell. MirBSD Korn shell mksh_ari_t ist ein 32-bit signed integer auch 
auf einem 64-bit System. ZSH weiß ich nicht. In android shell scripts 
ein typischer Fehler, da kann die Berechnung von Speicherplatz gern mal 
schief gehen.
Gast #7195612
Lesenswert?

Alexander schrieb:
> Das hat mit dem 64-bit System nichts zu tun, das ist abhängig von der
> Shell. MirBSD Korn shell mksh_ari_t ist ein 32-bit signed integer auch
> auf einem 64-bit System. ZSH weiß ich nicht. In android shell scripts
> ein typischer Fehler, da kann die Berechnung von Speicherplatz gern mal
> schief gehen.

Das mag durchaus sein, mir drängte sich allerdings seit dem 
Eröffnungs-Beitrag der Eindruck auf, das wir uns über die Bash 
unterhalten.
Der Gedanke wird auch durch das seinerzeit gezeigte Shebang mitgetragen. 
;-)
#7195677
Lesenswert?

Shebang wird möglicherweise übergangen wenn man das Script nicht korrekt 
als Executable aufruft. Abgesehen davon kann /bin/bash auch nur ein 
Symlink sein (so wie /bin/sh).

kurz: Wenn man weiß was man tut kann man auf Bash builtins zurück 
greifen, da kein extra Prozess gespawnt wird. Aber wenn man expr in 
fremden Scripts sieht sollte man erstmal drüber nachdenken ob dies nicht 
vielleicht einen Grund hat.
Gast #7195757
Lesenswert?

Alexander schrieb:
> Shebang wird möglicherweise übergangen wenn man das Script nicht
> korrekt als Executable aufruft.

$SHLVL

> Abgesehen davon kann /bin/bash auch nur ein
> Symlink sein (so wie /bin/sh).

zB: $_

Ja, mit selektierten Sonderfällen kann man alles erklären… ;-)
Aber ich denke ich lehne mich nicht all zu weit aus dem Fenster, wenn 
ich vermute das ganz oben eigentlich eine Einsteigerfrage gestellt 
wurde.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren