Christina hat geschrieben: ↑21. Sep 2020, 20:40
Wie schreibt man eigentlich in der bash die if-Anweisung korrekt? Mit doppelter eckiger Klammer [[…]] ?
Ich habe verschiedene Varianten im www gesehen.
Gräfin Klara hat geschrieben: ↑22. Sep 2020, 11:13
[ .. ] hat historische Gründe. Es läßt sich nicht ändern, nur erweitern, sonst würden Millionen alte scripts nicht mehr funktionieren.
[[ .. ]] ist neu, es bietet mehr und kann auch alles was [ .. ] kann. Denk nicht darüber nach, verwende [[ .. ]]
Dies Aussage greift aber sehr kurz.
Das eine ist intern in der Bash verbaut "[[ ... ]]"
man bash hat geschrieben:[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the conditional expression expression. Expressions are composed of the primaries described below under
CONDITIONAL EXPRESSIONS. Word splitting and pathname expansion are not performed on the words between the [[ and ]]; tilde expansion, parameter and variable
expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed. Conditional operators such as -f must be unquoted
to be recognized as primaries.
....
Das andere "[ ....... " ist nichts weiter als ein Hardlink (bzw heute oft eine anderes kompilierte Form) von /usr/bin/test
Code: Alles auswählen
robi@linux001 >which [
/usr/bin/[
robi@linux001 >ls -il /usr/bin/[
1053488 -rwxr-xr-x 1 root root 39704 17. Mär 2014 /usr/bin/[
robi@linux001 >ls -il /usr/bin/test
1055508 -rwxr-xr-x 1 root root 35616 17. Mär 2014 /usr/bin/test
Nachweisen kann man das zum Beispiel wenn man mal in den Binärcode reinschaut, hier mal als Beispiel ein Bereich wo die HELP Infomationen von beiden Binärdateien gegenüberstellt.
Code: Alles auswählen
robi@linux001 >strings /usr/bin/[ | grep FILE
FILE1 -ef FILE2 FILE1 and FILE2 have the same device and inode numbers
FILE1 -nt FILE2 FILE1 is newer (modification date) than FILE2
FILE1 -ot FILE2 FILE1 is older than FILE2
-b FILE FILE exists and is block special
-c FILE FILE exists and is character special
-d FILE FILE exists and is a directory
-e FILE FILE exists
-f FILE FILE exists and is a regular file
-g FILE FILE exists and is set-group-ID
-G FILE FILE exists and is owned by the effective group ID
-h FILE FILE exists and is a symbolic link (same as -L)
-k FILE FILE exists and has its sticky bit set
-L FILE FILE exists and is a symbolic link (same as -h)
-O FILE FILE exists and is owned by the effective user ID
-p FILE FILE exists and is a named pipe
-r FILE FILE exists and read permission is granted
-s FILE FILE exists and has a size greater than zero
-S FILE FILE exists and is a socket
-u FILE FILE exists and its set-user-ID bit is set
-w FILE FILE exists and write permission is granted
-x FILE FILE exists and execute (or search) permission is granted
Except for -h and -L, all FILE-related tests dereference symbolic links.
robi@linux001 >strings /usr/bin/test | grep FILE
FILE1 -ef FILE2 FILE1 and FILE2 have the same device and inode numbers
FILE1 -nt FILE2 FILE1 is newer (modification date) than FILE2
FILE1 -ot FILE2 FILE1 is older than FILE2
-b FILE FILE exists and is block special
-c FILE FILE exists and is character special
-d FILE FILE exists and is a directory
-e FILE FILE exists
-f FILE FILE exists and is a regular file
-g FILE FILE exists and is set-group-ID
-G FILE FILE exists and is owned by the effective group ID
-h FILE FILE exists and is a symbolic link (same as -L)
-k FILE FILE exists and has its sticky bit set
-L FILE FILE exists and is a symbolic link (same as -h)
-O FILE FILE exists and is owned by the effective user ID
-p FILE FILE exists and is a named pipe
-r FILE FILE exists and read permission is granted
-s FILE FILE exists and has a size greater than zero
-S FILE FILE exists and is a socket
-u FILE FILE exists and its set-user-ID bit is set
-w FILE FILE exists and write permission is granted
-x FILE FILE exists and execute (or search) permission is granted
Except for -h and -L, all FILE-related tests dereference symbolic links.
Damit ist beides etwas komplett anderes, das eine ist intern in der Bash verbaut und wird sofort ohne Umwege genutzt, (und kann wenn ich eine andere Shell als die Bash verwende anders funktionieren) und das andere ist ein eigenes Programm dazu muss erst ein neuer Prozess mittels forc erstellt werden, dann der Binärcode der Datei in den neuen Prozess geladen werden und dann der neue Prozess dort gestartet werdeb. Das ist genau so als wenn Subprozesse erstellt werden wie für jedes andere im Scriptcode verwendete (Basch)externe Tool auch. zB grep, sed, cat , find ..... .
Und kostet damit Zeit und Ressourcen und macht zB in großen Schleifen die Abarbeitung von Scripts langsam.
Auch die möglichen Optionen/Operatoren und Möglichkeiten sind recht verschieden.
Damit sollte man sich schon bewusst sein, das das [[ ]] und [ ] nicht wirklich das Gleiche oder nur Historisch-und-Nachfolger ist.
IF ist nun auch nicht unbedingt nur für [, [[ oder test bestimmt. In der Manpage von bash findet man die Definition.
[quote="man bash"
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
The if list is executed. If its exit status is zero, the then list is executed. Otherwise, each elif list is executed in turn, and if its exit status is zero,
the corresponding then list is executed and the command completes. Otherwise, the else list is executed, if present. The exit status is the exit status of the
last command executed, or zero if no condition tested true.
ich kann also hier eine Abfrage (if) auf das (End)Ergebniss einer ganzen Latte von Befehlen machen, Wenn der letzte Befehl in der Liste den Status 0 zurückgibt dann wird die Befehlsliste hinter then ausgeführt, sonst hinter else
Code: Alles auswählen
robi@linux001 >if ls ; ls -l ; ls -il | grep "File4" ; then echo vorhanden ; else echo nicht vorhanden ; fi
File1 File2 File3 File4 File5 File6
insgesamt 0
-rw-rw-r-- 1 puppe users 0 25. Sep 14:26 File1
-rw-rw-r-- 1 puppe users 0 25. Sep 14:26 File2
-rw-rw-r-- 1 puppe users 0 25. Sep 14:26 File3
-rw-rw-r-- 1 puppe users 0 25. Sep 14:26 File4
-rw-rw-r-- 1 puppe users 0 25. Sep 14:26 File5
-rw-rw-r-- 1 puppe users 0 25. Sep 14:26 File6
3021659 -rw-rw-r-- 1 puppe users 0 25. Sep 14:26 File4
vorhanden
hier wird als "TEST" zuerst "ls" ausgeführt, anschließend "ls -l" und anschließend "ls -il | grep File4"
Ausgewertet wird der Rückgabewert von grep und da grep was gefunden hat wird der then-Zweig durchlaufen, in dem natürlich dann auch wieder jede Menge Befehle in einer Liste stehen könnten.
Von da her ist if-then-else-fi in der Bash etwas mächtiger als in vielen Programmiersprachen, und man kann damit durchaus Programmabläufe programmieren, wo man sich extrem schwer tut dieses in eine andere Programmiersprache eins-zu-eins zu übersetzen. Allerdings werden hier die Möglichkeiten der Bash meist an dieser Stelle gar nicht richtig ausgenutzt, weil natürlich jeder "Programmierer" irgendwie hier in allgemein gültigen logischen Algorithmen denkt und damit selten die Möglichkeiten und Stärken von einzelnen Programmiersprachen aus Grundlage für die Optimierung eines Programmablauf zugrundelegt.
robi