Einen solchen Test auf "null string" als Inhalt von STDOUT einer Sub-Shell sieht man nicht soo häufig und selbst viele, die schon mal ein Shell-Skript geschrieben haben, müssen diese Syntax-Form nicht zwingend kennen.
Und wehe, diese Ausgabe enthält dann mehr als einen Wert (auch wenn das in #5 wegen des Ausdrucks nicht möglich ist (wenn man den Eingabewert vorher schon getestet hat, komme ich gleich noch einmal drauf zurück), bleibt es beim "Adaptieren" eine Falle, so man den Unterschied nicht kennt):
Code:
vidar:/tmp # test $(echo) && printf "true" || printf "false";printf "\n"
false
vidar:/tmp # test $(echo 1) && printf "true" || printf "false";printf "\n"
true
vidar:/tmp # test $(echo 1 2) && printf "true" || printf "false";printf "\n"
bash: test: 1: unary operator expected
false
vidar:/tmp # test "$(echo 1 2)" && printf "true" || printf "false";printf "\n"
true
vidar:/tmp # [ $(echo 1 2) ] && printf "true" || printf "false";printf "\n"
bash: [: 1: unary operator expected
false
vidar:/tmp #
Daher mein Tipp: Wenn man "die Wahl" hat, sollte man es (meine Meinung) dem "Leser" einfacher machen und tatsächlich einen Vergleich benutzen und sich nicht (erst recht nicht bei der Form von "test" mit den eckigen Klammern) auf die "test <string>"-Syntax verlassen und man sollte auch immer damit rechnen, daß ja mal ein "unerwarteter" Wert auftauchen könnte (hier für "$1" in der "test"-Funktion) und daher prinzipiell alle Zeichenketten (und die STDOUT einer Sub-Shell gehört definitiv dazu, denn was passiert denn beim Aufruf von
Code:
vidar:/tmp # test(){ if [ $(echo $1 | egrep '([01][0-9]|2[0-3]):[0-5][0-9]') ]; then echo ok; else echo fail; fi }
vidar:/tmp # test "01:00 02:00"
bash: [: 01:00: unary operator expected
fail
vidar:/tmp #
) passend ein- bzw. umschließen, dann kann das auch keine bösen Überraschungen geben:
Code:
vidar:/tmp # test(){ if [ "$(echo $1 | egrep '([01][0-9]|2[0-3]):[0-5][0-9]')" ]; then echo ok; else echo fail; fi }
vidar:/tmp # test "01:00 02:00"
ok
vidar:/tmp #
... ob das dann tatsächlich noch "ok" ist oder nicht, muß jeder selbst entscheiden.
Denn so ein "egrep" liefert eben auch dann noch ein Ergebnis, wenn das nur
irgendwo in der Zeile steht:
Code:
vidar:/tmp # echo "01:00" | egrep '([01][0-9]|2[0-3]):[0-5][0-9]'
01:00
vidar:/tmp # echo "01:00 02:00" | egrep '([01][0-9]|2[0-3]):[0-5][0-9]'
01:00 02:00
vidar:/tmp # echo "01:00 02:00 ABCDEFGH" | egrep '([01][0-9]|2[0-3]):[0-5][0-9]'
01:00 02:00 ABCDEFGH
... also sollte man noch zusätzlich die Forderung aufstellen, daß die gesamte Zeile auf das Muster paßt:
Code:
vidar:/tmp # echo "01:00 02:00 ABCDEFGH" | egrep '^([01][0-9]|2[0-3]):[0-5][0-9]$'
vidar:/tmp # echo "01:00" | egrep '^([01][0-9]|2[0-3]):[0-5][0-9]$'
01:00
vidar:/tmp #
Fazit:
Manchmal ist es tatsächlich eine Herausforderung, Shell-Code so zu formulieren, daß er auch wirklich "idiotensicher" ist und sich auch von unerwarteten Eingabewerten nicht wirklich aus der Ruhe bringen läßt.