Was ist der Zweck der eckigen Klammer ausführbar

27

Ich sehe, es gibt eine ausführbare Datei mit dem Namen "[" in /usr/bin. Was ist seine Aufgabe?

Bildbeschreibung hier eingeben

Alexandru Irimiea
quelle

Antworten:

33

In den meisten Fällen [ist eine Shell eingebaut und entspricht test. Wie auch immer test, es gibt es auch als eigenständige ausführbare Datei: das ist die, die /bin/[Sie gesehen haben. Sie können dies testen mit type -a [(auf einem Arch Linux-System, das ausgeführt wird bash):

$ type -a [
[ is a shell builtin
[ is /bin/[

Also habe ich auf meinem System zwei [: die eingebaute Shell und die ausführbare Datei /bin. Die ausführbare Datei ist dokumentiert in man test:

TEST(1)                          User Commands                         TEST(1)

NAME
       test - check file types and compare values

SYNOPSIS
       test EXPRESSION
       test

       [ EXPRESSION ]
       [ ]
       [ OPTION

DESCRIPTION
       Exit with the status determined by EXPRESSION.

[ ... ]

Wie Sie im Auszug der oben zitierten Manpage sehen können testund [gleichwertig sind. Die Befehle /bin/[und /bin/testwerden von POSIX angegeben, weshalb Sie sie finden, obwohl viele Shells sie auch als integrierte Befehle bereitstellen. Ihre Anwesenheit stellt sicher, dass Konstrukte wie:

[ "$var" -gt 10 ]  && echo yes

funktioniert auch dann, wenn die Shell, auf der sie ausgeführt werden, kein [eingebautes Programm hat. Zum Beispiel in tcsh:

> which [
/sbin/[
> set var = 11
> [ "$var" -gt 10 ]  && echo yes
yes
terdon
quelle
5
@AlexandruIrimiea was meinst du? Eine Shell ohne [eingebauten Code ist nur eine Shell, deren Autoren beschlossen haben, keine Shell hinzuzufügen. tcsh nicht über eine [eingebaute zum Beispiel.
Terdon
7
@AlexandruIrimiea sie sind nicht "benutzerdefinierte" Muscheln. Dies bashist nur eines von vielen Programmen (Shells), die für ähnliche Aufgaben entwickelt wurden. Bash ist eines der beliebtesten, aber viele Systeme werden mit unterschiedlichen Standard-Shells ausgeliefert. Einige der besser bekannten sind sh, bash, zsh, dash, ksh, tcsh, cshund fish. Sie können die auf Ihrem System verfügbaren mit cat /etc/shellsund eine Teilliste hier sehen .
Terdon
1
@ JörgWMittag wirklich? Ich wusste, dass Ubuntu shist, dashaber ich dachte, das Rettungssystem verwendet /bin/shkeine Busybox. Bist du sicher?
Terdon
2
Wie aus dieser Frage hervorgeht
Sergiy Kolodyazhnyy
1
@AlexandruIrimiea, in Bezug auf welche Befehle ist es notwendig , in gebaut zu haben und welche Befehle können oder nicht in, sehen gebaut werden diesen Beitrag .
Wildcard
12

Dies wird zum Testen von Bedingungen in Shell-Skripten verwendet. Ein anderer Name dieses Programms ist test:

if [ 1 -lt 2 ]; then ...

Das sieht aus wie Shell-Grammatik, ist es aber nicht. Normalerweise [ist eine Shell eingebaut, aber wahrscheinlich als Fallback existiert sie als externer Befehl.

Siehe den Block "Bedingte Ausdrücke" in man bash.

Hauke ​​Laging
quelle
9

[ist der gleiche Befehl wie test. Auf einigen * nix-Systemen ist eines nur eine Verknüpfung zum anderen. Wenn Sie beispielsweise Folgendes ausführen:

strings /usr/bin/test 
strings /usr/bin/[

Sie sehen die gleiche Ausgabe.

Die meisten Shells / Posix-Shells enthalten Builtin [und testBefehle. Gleiches gilt für echo. /bin/echoIn den meisten Shells gibt es sowohl einen Befehl als auch einen eingebauten Befehl. Das ist der Grund, warum Sie manchmal das Gefühl haben, dass zum Beispiel echoauf verschiedenen Systemen nicht dasselbe funktioniert.

testoder [nur einen Exit-Code von 0oder zurückgeben 1. Wenn der Test erfolgreich war, lautet der Beendigungscode 0.

# you can use [ command but last argument must be ] 
# = inside joke for programmers 
# or use test command. Args are same, but last arg can't be ] :)
# so you can't write 
#    [-f file.txt] because [-f is not command and last argument is not ]
# after [ have to be delimiter as after every commands
[ -f file.txt ] && echo "file exists" || echo "file does not exist"
test -f file.txt && echo "file exists" || echo "file does not exist"
[ 1 -gt 2 ] && echo yes || echo no
test 1 -gt 2  && echo yes || echo no
# use external command, not builtin
/usr/bin/[ 1 -gt 2 ] && echo yes || echo no

Sie können auch [mit if:

if [ -f file.txt ] ; then
  echo "file exists" 
else 
  echo "file does not exist"
fi
# is the same as
if test -f file.txt  ; then
  echo "file exists" 
else 
  echo "file does not exist"
fi

Aber Sie können ifmit jedem Befehl ifExit-Code testen. Beispielsweise:

cp x y 2>/dev/null && echo cp x y OK ||  echo cp x y not OK

Oder mit if:

if cp x y 2>/dev/null ; then
   echo cp x y OK
else
   echo cp x y not OK
fi

Sie können dasselbe Ergebnis nur mit dem testBefehl zum Testen des Exit-Codes erhalten, der in der Variablen gespeichert ist stat:

cp x y 2>/dev/null 
stat=$?
if test "$stat" = 0 ; then
   echo cp x y OK
else
   echo cp x y not OK
fi

Sie können auch [[ ]]und (( ))zum Testen verwenden, aber diese sind nicht dieselben wie [und test, obwohl sie fast dieselbe Syntax haben:

Um herauszufinden, was ein Befehl ist, können Sie Folgendes verwenden:

type -a command
kshji
quelle
Zum Vergleichen von Dateien sollten Sie lieber cmp /usr/bin/[ /usr/bin/testHashes verwenden oder vielleicht sha256sum /usr/bin/[ /usr/bin/testaber nicht strings. Auf meinem System (openSUSE Tumbleweed) sind sie übrigens nicht gleich (warum auch immer).
Hauke ​​Laging
Ich habe nicht Byte-Vergleiche gemeint. In einigen * nix sind sie gleich auch in Byte-Ebene = verknüpft. Posix-Test
kshji