Bash-Code: Bitte um Verständnishilfe
![](https://seccdn.libravatar.org/avatar/7b00a083f1ae016459c8044116b13075.jpg?s=120&d=mm&r=g)
Hallo zusammen, es geht um folgende Zeile(n): ---- if [ $RV -eq 0 -a ! -z "$FILE" ]; then ... fi ---- Ich bin nun wahrlich kein Meister der Bash, aber verstehen möchte ich das trotzdem. (Also das dass eine Verzweigung ist (oder sein soll?) habe ich schon begriffen ;-) Aber ich kann die Bedingung nicht entwirren. Also: if [ $RV -eq 0 Wenn $RV gleich 0 ist, aber dann: -a ! ??? der Rest: -z "$FILE" ]; then wenn $FILE leer ist, dann ... u.s.w. das habe ich so aus einem Startskript was nur teilweise läuft. Kopfkratz Bernd -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/27023f5ba9c8e122060340126d06642c.jpg?s=120&d=mm&r=g)
Hi Bernd! On Fr, 10 Jun 2011, Bernd Nachtigall wrote:
if [ $RV -eq 0 Wenn $RV gleich 0 ist, aber dann: -a !
-a AND
-z "$FILE" ]; then
! -z "$FILE" $FILE nicht leer ist. Mit freundlichen Grüßen Christian -- Toleranz sollte eigentlich nur eine vorübergehende Gesinnung sein: Sie muss zur Anerkennung führen. Dulden heißt beleidigen. -- Goethe, Maximen und Reflektionen, Nr. 545 -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/7b00a083f1ae016459c8044116b13075.jpg?s=120&d=mm&r=g)
Am Freitag, 10. Juni 2011 schrieb Christian Brabandt:
-a !
-a AND
... ich hatte das (aus syntaktischen Gründen) vermutet, aber -a als logische Verknüpfung ... Wieder was gelernt, danke :-) -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/b1966ffac861531a1d6494248e650a12.jpg?s=120&d=mm&r=g)
* Bernd Nachtigall (bnacht@web.de) [20110610 12:54]:
if [ $RV -eq 0 -a ! -z "$FILE" ]; then
Die Bedingung ist: Wenn $RV gleich 0 ist UND die Länge des Strings "$FILE" nicht 0 ist Syntax nachzulesen in 'man 1 test' Philipp -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/05ed3ad6426b2b890735149d2d779c37.jpg?s=120&d=mm&r=g)
Am Freitag, 10. Juni 2011, 12:54:21 schrieb Bernd Nachtigall:
Hallo zusammen,
es geht um folgende Zeile(n):
---- if [ $RV -eq 0 -a ! -z "$FILE" ]; then ... fi ----
Ich bin nun wahrlich kein Meister der Bash, aber verstehen möchte ich das trotzdem. (Also das dass eine Verzweigung ist (oder sein soll?) habe ich schon begriffen ;-) Aber ich kann die Bedingung nicht entwirren. Bei so etwas hilft immer ein "man test", denn test heißt das Programm, welches zwischen "[" und "]" ausgeführt wird.
Wörtlich heißt obiges: Wenn $RV gleich (-eq) 0 ist UND (-a) $FILE nicht (!) leer (-z) ist, dann mache... Liebe Grüße Felix
![](https://seccdn.libravatar.org/avatar/7b00a083f1ae016459c8044116b13075.jpg?s=120&d=mm&r=g)
(...)
Bei so etwas hilft immer ein "man test", denn test heißt das Programm, welches zwischen "[" und "]" ausgeführt wird. (...)
Hallo Felix, hallo Philipp, jepp, ich hatte da wohl schon zu lange drauf geguckt §-| ... und als dann ein 'man if' nix ergab ... Aber jetzt ist es klar, zwischen den [] läuft 'test'. Danke Bernd -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/638c5f9b9a41e53d4663197a58261c49.jpg?s=120&d=mm&r=g)
Hallo, Am Fri, 10 Jun 2011, Bernd Nachtigall schrieb:
(...)
Bei so etwas hilft immer ein "man test", denn test heißt das Programm, welches zwischen "[" und "]" ausgeführt wird. (...)
jepp, ich hatte da wohl schon zu lange drauf geguckt §-| ... und als dann ein 'man if' nix ergab ... Aber jetzt ist es klar, zwischen den [] läuft 'test'.
Deswegen empfehle und verwende ich immer test explizit. Also: if test "$RV" -eq 0 -a -n "$FILE"; then Verwendet wird dabei normalerweise das shell-builtin "test", dokumentiert per 'help test' (man bashbuiltins): -z STRING True if string is empty. -n STRING STRING True if string is not empty EXPR1 -a EXPR2 True if both expr1 AND expr2 are true. arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne, -lt, -le, -gt, or -ge. Arithmetic binary operators return true if ARG1 is equal, not-equal, less-than, less-than-or-equal, greater-than, or greater-than-or-equal than ARG2 Hilft auch dabei nicht "von hinten durch die Brust ins Auge" wie: if [ `grep bla /blubb | wc -l` -gt 0 ] ; then was man besser per if grep -q bla /blubb; then erledigen sollte (ggfs. >/dev/null anhängen statt '-q' wenn's portabel sein soll). HTH, -dnh -- 281: Personal Firewall Warum installieren Sie sich ein Programm, mit dessen Ausgaben Sie dann nichts anzufangen wissen? (T-Online-Team) -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/27023f5ba9c8e122060340126d06642c.jpg?s=120&d=mm&r=g)
Hi Bernd! On Fr, 10 Jun 2011, Bernd Nachtigall wrote:
jepp, ich hatte da wohl schon zu lange drauf geguckt §-| ... und als dann ein 'man if' nix ergab ... Aber jetzt ist es klar, zwischen den [] läuft 'test'.
Nö. Witzigerweise ist [ ein eigenes binary: #v+ ls -li /usr/bin/{[,test} 148517 -rwxr-xr-x 1 root root 28300 28. Apr 2010 /usr/bin/[ 1126088 -rwxr-xr-x 1 root root 26364 28. Apr 2010 /usr/bin/test #v- In den meisten Shells, wird aber test bzw. [ als selber implementiert, was bedeutet, dass diese Binaries von der Shell gar nicht mehr aufgerufen werden (und daher auch oft andere Features unterstützen) Ich habe ja immer gedacht, dass eines der beiden binaries auf das andere hardgelinkt ist. Das sieht aber nicht so aus. Jetzt frag mich aber nicht, was die Unterschiede zwischen beiden sind. Mit freundlichen Grüßen Christian -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/638c5f9b9a41e53d4663197a58261c49.jpg?s=120&d=mm&r=g)
Hallo, Am Sat, 11 Jun 2011, Christian Brabandt schrieb:
Nö. Witzigerweise ist [ ein eigenes binary:
#v+ ls -li /usr/bin/{[,test} 148517 -rwxr-xr-x 1 root root 28300 28. Apr 2010 /usr/bin/[ 1126088 -rwxr-xr-x 1 root root 26364 28. Apr 2010 /usr/bin/test #v-
Hab mal eben coreutils-8.9 von gnu.org gesaugt und gebaut. Ah. Irgendwann sind die GNUler wohl auf die glorreiche Idee gekommen, /bin/test (ist per "define" aber umschaltbar) zu nem 'dummy' binary zu machen, das wohl (soweit ich das auf den ersten Blick verstehe) das shell-builtin test "anspringt". Das "echte" test gibt's dann als '['. Siehe src/lbracket.c (ein define + include) und src/test.c in den coreutils sourcen. IMO ein sehr seltsame Entscheidung. Naja, anderswo fragt man sich ja AFAIK gerüchtehalber schon länger, was die GNUler so alles rauchen.
In den meisten Shells, wird aber test bzw. [ als selber implementiert, was bedeutet, dass diese Binaries von der Shell gar nicht mehr aufgerufen werden (und daher auch oft andere Features unterstützen)
Genau. "Shell Builtin". /usr/bin/test und /usr/bin/[ sollten "im Normalbetrieb" nicht aufgerufen werden. Auch in busybox/sash sind beide mit drin. Deswegen auch mein Hinweis auf help test / man bashbuiltins nebenan. Und 'test ...' statt '[ ... ]' ist schon wg. der nötigen Leerzeichen vor und nach '[' und vor ']' sinnvoll. Das '[' ist eben keine Shell-Syntax wie '{', '(', '[[' und '((' (sowie $() und $(())). Das sind beliebte Anfängerfallen. Mit 'test' hat man das Problem nicht und der Anfänger lernt auch gleich, daß sie/er mit z.B. 'if' _JEDES_ Programm oder Builtin, das bei Erfolg 0 und sonst was != 0 liefert verwenden kann. 'test' ist nur ein leicht überdurchschnittlich häufig verwendetes.
Ich habe ja immer gedacht, dass eines der beiden binaries auf das andere hardgelinkt ist. Das sieht aber nicht so aus. Jetzt frag mich aber nicht, was die Unterschiede zwischen beiden sind.
So war's auch mal. Use the source, Lu^WChris! ==== Changelog* ==== 2003-06-30 Paul Eggert <eggert@twinsun.com> Add support for a "[" that conforms to the GNU coding standards, i.e., that does not depend on its name. * src/lbracket.c: New file. * README: Add "[". * man/Makefile.am (programs): Ignore "[", since it doesn't have a separate man page. * src/Makefile.am (bin_PROGRAMS): Add "[". (__SOURCES): New var. * src/test.c (LBRACKET): Define to 0 if not defined. (main): Use LBRACKET rather than argv[0]. * src/test.c (one_argument): Do not check for -t if POSIXLY_CORRECT. Reported by Paul Jarc and Dan Jacobson. * src/test.c (main): Do not recognize --help or --version if POSIXLY_CORRECT, when invoked as "test". Handle "[ ]" correctly. Do not bother testing that margv[margc] is non-null. ==== das müßte es sein. ==== NEWS ==== * Major changes in release 5.0.1 (2003-07-15): ** New programs - new program: `[' (much like `test') ==== Äh, ich verkneif mir jetzt mal nen Kommentar. Bei Interesse könnte ich mal meine und mir geschenkten SUSE CDs/DVDs einwerfen und schauen, ab welcher Version [ und test keine hardlinks mehr sind. (Hm, da fällt mir ein, ich hab schon so einige ISO images auf der Platte ... und dann könnte man auch noch /var/lib/pin auffüllen ... ;) -dn'oldschool'h PS: diesmal keine Zufallssig. -- "Anybody who really thinks /bin/true should report a version number and a help string (or even a copyright notice) needs to get his head examined." -- Linus Torvalds -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/d8110a8a8a97be0803549ea5ee2e638b.jpg?s=120&d=mm&r=g)
Am 11. Juni 2011 16:49 schrieb David Haller <dnh@opensuse.org>:
coreutils sourcen. IMO ein sehr seltsame Entscheidung. Naja, anderswo fragt man sich ja AFAIK gerüchtehalber schon länger, was die GNUler so alles rauchen.
:-) Achja: -a und -o sind XSI extensions, also nicht wirklich portabel (aber das dürfte nur auf Unixen aus dem letzten Jahrtausend relevant sein :). Gruß Martin -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/638c5f9b9a41e53d4663197a58261c49.jpg?s=120&d=mm&r=g)
Hallo, Am Sat, 11 Jun 2011, Martin Schröder schrieb:
Am 11. Juni 2011 16:49 schrieb David Haller <dnh@opensuse.org>:
coreutils sourcen. IMO ein sehr seltsame Entscheidung. Naja, anderswo fragt man sich ja AFAIK gerüchtehalber schon länger, was die GNUler so alles rauchen.
:-)
Achja: -a und -o sind XSI extensions, also nicht wirklich portabel (aber das dürfte nur auf Unixen aus dem letzten Jahrtausend relevant sein :).
Aber selbst dann gilt das in http://pubs.opengroup.org/onlinepubs/009695399/utilities/test.html genannte: ==== APPLICATION USAGE Scripts should be careful when dealing with user-supplied input that could be confused with primaries and operators. Unless the application writer knows all the cases that produce input to the script, invocations like: test "$1" -a "$2" should be written as: test "$1" && test "$2" to avoid problems if a user supplied values such as $1 set to '!' and $2 set to the null string. That is, in cases where maximal portability is of concern, replace: test expr1 -a expr2 with: test expr1 && test expr2 [..] ==== (hab jetzt auf die Schnelle nix aktuelleres gefunden (vielmehr will ich mir jetzt nicht durch die Seite wühlen sondern greif auf was altes zu)). Kurzum, mit '-a' und '-o' sollte man vorsichtig sein. Ich vermeide mehrfach-Bedingungs-test generell, bzw. greife dann eben wenn sowas nötig wird gerne gleich zu awk oder noch eher perl ;) Das ist eben auch ein Indiz dafür (aber nicht mehr), daß das Script so komplex zu werden droht, daß es sich lohnt awk oder perl zu verwenden. YMMV. Aber je nach Kontext (init-Script) gibt's weitere Parameter. -dnh -- Hehehe: Der LaTeX Benutzer flucht halt auf den ersten zehn Seiten. Der Word-Mensch auf den danach folgenden. -- Karl Wunderle -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/27023f5ba9c8e122060340126d06642c.jpg?s=120&d=mm&r=g)
Hi Martin! On Sa, 11 Jun 2011, Martin Schröder wrote:
Am 11. Juni 2011 16:49 schrieb David Haller <dnh@opensuse.org>:
coreutils sourcen. IMO ein sehr seltsame Entscheidung. Naja, anderswo fragt man sich ja AFAIK gerüchtehalber schon länger, was die GNUler so alles rauchen.
:-)
Achja: -a und -o sind XSI extensions, also nicht wirklich portabel (aber das dürfte nur auf Unixen aus dem letzten Jahrtausend relevant sein :).
Es hat es in POSIX geschafft, damit würde ich mich auch darauf verlassen. Mit freundlichen Grüßen Christian -- Wenn man Roland Koch mit irgendwelchen Nazigrößen vergleicht, da muß man aufpassen, da gibt es einen Paragraphen. Das ist Verunglimpfung des Andenkens Verstorbener. -- Werner Koczwara -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/27023f5ba9c8e122060340126d06642c.jpg?s=120&d=mm&r=g)
Hi David! On Sa, 11 Jun 2011, David Haller wrote:
Hab mal eben coreutils-8.9 von gnu.org gesaugt und gebaut. Ah.
;) Ich habe kurz überlegt, aber so wichtig war es mir dann nicht.
Irgendwann sind die GNUler wohl auf die glorreiche Idee gekommen, /bin/test (ist per "define" aber umschaltbar) zu nem 'dummy' binary zu machen, das wohl (soweit ich das auf den ersten Blick verstehe) das shell-builtin test "anspringt". Das "echte" test gibt's dann als '['.
Siehe src/lbracket.c (ein define + include) und src/test.c in den coreutils sourcen. IMO ein sehr seltsame Entscheidung. Naja, anderswo fragt man sich ja AFAIK gerüchtehalber schon länger, was die GNUler so alles rauchen.
Interessant. Danke fürs nachschauen.
So war's auch mal. Use the source, Lu^WChris!
Ja, beim nächsten Mal ;)
PS: diesmal keine Zufallssig. -- "Anybody who really thinks /bin/true should report a version number and a help string (or even a copyright notice) needs to get his head examined."
Haha, das frag ich mich ja auch schon lange: #v+ chrisbra@host: ls -l /bin/true -rwxr-xr-x 1 root root 16060 28. Apr 2010 /bin/true #v- 16K für ein /bin/true, da werden bestimmt noch Primzahlen berechnet oder so. Und /bin/true --version bzw --help funktioniert ja auch. Das ist ja fast so gut, wie das /bin/echo --version und /bin/echo --help Mit freundlichen Grüßen Christian -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/638c5f9b9a41e53d4663197a58261c49.jpg?s=120&d=mm&r=g)
Hallo, Am Mon, 13 Jun 2011, Christian Brabandt schrieb:
PS: diesmal keine Zufallssig. -- "Anybody who really thinks /bin/true should report a version number and a help string (or even a copyright notice) needs to get his head examined."
Haha, das frag ich mich ja auch schon lange:
#v+ chrisbra@host: ls -l /bin/true -rwxr-xr-x 1 root root 16060 28. Apr 2010 /bin/true #v-
16K für ein /bin/true, da werden bestimmt noch Primzahlen berechnet oder so.
Auf meiner ex-6.2/32bit mit Kernel 2.4.x hatte ich die tinyutils (oder so) Version von /bin/true. 45 Bytes hat das Binary. Läuft leider nicht unter x64_64 (SEGFAULT). Siehe: http://www.muppetlabs.com/%7Ebreadbox/software/tiny/ true.asm source [..] This program returns an exit code of either zero or one, depending on whether it is invoked with the name "true" or "false", respectively. This one is the runt of the litter. Its size is 45 bytes. Count them. This is the smallest it is possible for a Linux ELF executable to be. So, und ich hab jetzt mal (zwar deutlich größere, aber dennoch in gewisserweise minimale true/false gebastelt), für noch kleinere fehlt mir a) das Assembler / ELF Wissen und b) auch der Ehrgeiz. ==== true64.asm.in ==== ;; true64.asm.in: (c) dnh@opensuse.org based on ;; http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html ;; GNU General Public License (version 2 or later). No warranty. BITS 64 GLOBAL _start SECTION .text _start: mov eax, 1 mov ebx, @RETVAL@ int 0x80 ==== ==== Makefile ==== # Makefile for true64.asm.in: (c) dnh@opensuse.org based on # http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html # GNU General Public License (version 2 or later). No warranty. BIN=true false all: $(BIN) true: true.o false: false.o true64.asm: true64.asm.in sed 's/@RETVAL@/0/;' $< > $@ false64.asm: true64.asm.in sed 's/@RETVAL@/1/;' $< > $@ %.o: %64.asm nasm -f elf64 -o $@ $< %: %.o gcc -Wall -s -nostdlib -o $@ $< clean: $(RM) *64.asm *.o $(BIN) ==== Beide Dateien in ein Verzeichnis rein, und per 'make' bauen. Installation ins System bitte nur nach eigenen Tests per Hand. Braucht make, sed, nasm und gcc. $ ls -l true false -rwxr-xr-x 1 dh dh 528 Jun 13 17:59 false -rwxr-xr-x 1 dh dh 528 Jun 13 17:59 true Geht doch halbwegs ;) $ ls -l `which true` `which false` -rwxr-xr-x 1 root root 528 Jun 13 18:02 /bin/false -rwxr-xr-x 1 root root 528 Jun 13 18:02 /bin/true $ file `which true` `which false` /bin/true: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped /bin/false: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped Im Vergleich zu den GNU Varianten massiv schlanker ;) Allerdings: in der Praxis ist obiges eher irrelevant: der entsprechende Code aus der glibc (der GNU true/false so fett macht) ist sowieso im RAM, und der Textkram (Version, --help) ist dann auch nicht so fett. Aber: Linus hat recht. Ergo ... -dnh -- BUGS It is not yet possible to change operating system by writ ing to /proc/sys/kernel/ostype. -- Linux sysctl(2) manpage -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
participants (6)
-
Bernd Nachtigall
-
Christian Brabandt
-
David Haller
-
Felix Lemke
-
Martin Schröder
-
Philipp Thomas