Forum: PC-Programmierung Warum läuft dieses Bash-Skript nicht korrekt??


von Bashboy (Gast)


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!

von Zeno (Gast)


Lesenswert?

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

von Norbert (Gast)


Lesenswert?

Bashboy schrieb:

> if ["$DIFFERENCE" -gt "$MINTIME"]


›[‹ ist ein Befehl (und zwar ›test‹

›[‹ möchte gerne von Leerzeichen umringt sein damit es funktioniert.

von Bashboy (Gast)


Lesenswert?

Fehler gefunden!

Es gehört ein Abstand nach und vor der eckigen Klammer!
1
if [ "$DIFFERENCE" -gt "$MINTIME" ]

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

LOL. Was für ein bescheuerter Parser wenn der mit sowas nicht klarkommt.

von (prx) A. K. (prx)


Lesenswert?

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

Das Verständnis kommt, wenn man kapiert, was da abgeht. Dann merkt man 
nämlich, dass da kein Parser am Werk ist, sondern ein Programm namens 
"[".

von Norbert (Gast)


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.

von Benj (Gast)


Lesenswert?

Nimm doch einfach "time" um zu messen wie lange ein Befehl braucht, 
dafür ist es da.


$ time sleep 1

real  0m1.003s
user  0m0.001s
sys  0m0.000s

von Zeno (Gast)


Lesenswert?

Norbert schrieb:
> ›[‹ ist ein Befehl (und zwar ›test‹
>
> ›[‹ möchte gerne von Leerzeichen umringt sein damit es funktioniert.
Das habe ich übersehen.

von (prx) A. K. (prx)


Lesenswert?

Benj schrieb:
> $ time sleep 1

Oder wenn man eine bestimmte Zeit in Sekunden will:
$ /usr/bin/time -f"%e" sleep 1
1.00

von Onkel Ted (Gast)


Lesenswert?

(prx) A. K. schrieb:
> $ /usr/bin/time -f"%e" sleep 1

Ist deine Pfadvariable kaputt oder wozu der absolute Pfad?

von (prx) A. K. (prx)


Lesenswert?

Onkel Ted schrieb:
> Ist deine Pfadvariable kaputt oder wozu der absolute Pfad?

Ausprobiert? In bash ist "time" intern und kann mit -f nichts anfangen.

: Bearbeitet durch User
von Ein T. (ein_typ)


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.

von (prx) A. K. (prx)


Lesenswert?

Onkel Ted schrieb:
> Ist deine Pfadvariable kaputt oder wozu der absolute Pfad?
1
$ /usr/bin/time sleep 1
2
0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 1900maxresident)k
3
0inputs+0outputs (0major+77minor)pagefaults 0swaps
4
5
$ time sleep 1
6
7
real  0m1,002s
8
user  0m0,000s
9
sys  0m0,001s

von Ein T. (ein_typ)


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.

Mit -v übrigens auch nicht -- dabei ist das ausgesprochen nützlich. ;-)

von Norbert (Gast)


Lesenswert?

bash. Nennt sich bash!
1
A=10 && B=12 && echo $((  $A  -  $B  ))
2
# -2

von Ein T. (ein_typ)


Lesenswert?

Norbert schrieb:
> bash. Nennt sich bash!
>
1
A=10 && B=12 && echo $((  $A  -  $B  ))
2
> # -2
3
>

Huch, stimmt, da hat mein Gehirn ein "expr" in das $(()) 
hineingepfuscht. Aber $(expr $A - $B) funktioniert natürlich trotzdem.

von Onkel Ted (Gast)


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

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Dann sag ich's anders: Was für eine bescheuerte "Programmiersprache"!

von Norbert (Gast)


Lesenswert?

Ben B. schrieb:
> Dann sag ich's anders: Was für eine bescheuerte
> "Programmiersprache"!

Tja, es ist nun auf geradezu schmerzhafte Weise offensichtlich das es 
völlig egal ist was du sagst. Es wird einfach nicht besser.
In solchen Fällen rate ich immer zu einem Buch.

von Jens G. (jensig)


Lesenswert?

Ben B. schrieb:
> Dann sag ich's anders: Was für eine bescheuerte
> "Programmiersprache"!

Immer noch nichts begriffen ...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Ben B. schrieb:
> Dann sag ich's anders: Was für eine bescheuerte "Programmiersprache"!

Vieles, was man nicht kennt, wirkt auf den ersten Blick merkwürdig.

von Herbert B. (Gast)


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.

von Norbert (Gast)


Lesenswert?

Herbert B. schrieb:
> Gewöhn dir an [[ ]] zu verwenden,

Dann sollte das Shebang aber besser präzise auf bash hinweisen, sonst 
scheppert's.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


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.

von (prx) A. K. (prx)


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.

: Bearbeitet durch User
von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

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.

von MaWin (Gast)


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.

Und dieser Unfall von Dos-Batch ist besser?

von (prx) A. K. (prx)


Lesenswert?

Vielleicht steht er auf JCL als Scriptsprache.
Ist von 1964 und immer noch in Gebrauch.

: Bearbeitet durch User
von Simu (Gast)


Lesenswert?

Sind Lochkarten eigentlich Software oder Hardware?

von Mombert H. (mh_mh)


Lesenswert?

MaWin schrieb:
> Und dieser Unfall von Dos-Batch ist besser?
Es geht ihm ja nicht um besser oder schlechter, es geht um 
unreflektierten Hass ...
Ben B. schrieb:
> Ganz ehrlich, ich hab Unix und seinen Ziehsohn schon immer gehasst.

von Ich A. (alopecosa)


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? ;)

von mIstA (Gast)


Lesenswert?

Simu schrieb:
> Sind Lochkarten eigentlich Software oder Hardware?

Datenträger, also Hardware.

von (prx) A. K. (prx)


Lesenswert?

mIstA schrieb:
>> Sind Lochkarten eigentlich Software oder Hardware?
>
> Datenträger, also Hardware.

Was aber sind die Löcher in der Karte?

von Yalu X. (yalu) (Moderator)


Lesenswert?

(prx) A. K. schrieb:
> mIstA schrieb:
>>> Sind Lochkarten eigentlich Software oder Hardware?
>>
>> Datenträger, also Hardware.
>
> Was aber sind die Löcher in der Karte?

Vaporware.

von Gerhard Z. (germel)


Lesenswert?

Leute, ich danke euch für diesen informativen Thread ohne das hier oft 
übliche Alphatier-Gehabe. Als jemand, der immer mal wieder kurze Bash 
Scripts schreibt lernt man gerne dazu und bekommt Anregungen!

von Alexander (alecxs)


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

: Bearbeitet durch User
von Norbert (Gast)


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. ;-)

von Walter K. (walter_k488)


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 ;-)

von Alexander (alecxs)


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.

von Norbert (Gast)


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. 
;-)

von Alexander (alecxs)


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.

: Bearbeitet durch User
von Norbert (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.