À quoi sert l'exécutable entre crochets

27

Je vois qu'il y a un exécutable appelé "[" dans /usr/bin. Quel est son objectif?

entrez la description de l'image ici

Alexandru Irimiea
la source

Réponses:

33

Dans la plupart des cas, [est un shell intégré et est équivalent à test. Cependant, testil existe également en tant qu'exécutable autonome: c'est ce que /bin/[vous avez vu. Vous pouvez tester cela avec type -a [(sur un système Arch Linux, en cours d'exécution bash):

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

Donc, sur mon système, j'en ai deux [: le shell de mon shell et l'exécutable /bin. L'exécutable est documenté dans 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.

[ ... ]

Comme vous pouvez le voir dans l'extrait de la page de manuel citée ci-dessus, testet [sont équivalentes. Les commandes /bin/[et /bin/testsont spécifiées par POSIX, c'est pourquoi vous les trouverez malgré le fait que de nombreux shells les fournissent également en tant que commandes intégrées. Leur présence garantit que des constructions comme:

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

fonctionnera même si le shell qui les exécute n'a pas de fonction [intégrée. Par exemple, dans tcsh:

> which [
/sbin/[
> set var = 11
> [ "$var" -gt 10 ]  && echo yes
yes
terdon
la source
5
@AlexandruIrimiea que voulez-vous dire? Un shell qui n'a pas la fonction [intégrée n'est qu'un shell dont les auteurs ont décidé de ne pas en ajouter un. tcsh ne dispose pas d' un [builtin par exemple.
terdon
7
@AlexandruIrimiea ce ne sont pas des coquilles "personnalisées". C'est juste que ce bashn'est qu'un des nombreux programmes (shells) conçus pour effectuer des tâches similaires. Bash est l'un des plus populaires, mais de nombreux systèmes sont livrés avec des shells par défaut différents. Certains de ceux plus connus sont sh, bash, zsh, dash, ksh, tcsh, cshet fish. Vous pouvez voir ceux disponibles sur votre système avec cat /etc/shellset une liste partielle ici .
terdon
1
@ JörgWMittag vraiment? Je savais qu'Ubuntu l' shest, dashmais je pensais que le système de sauvetage n'utilisait /bin/shpas la boîte occupée. Êtes-vous sûr?
terdon
2
Cependant, il y a en effet une
boîte occupée
1
@AlexandruIrimiea, concernant les commandes qu'il est nécessaire d'avoir intégrées et quelles commandes peuvent ou non être intégrées, voir ce post .
Wildcard
12

Utilisé pour les tests de condition dans les scripts shell. Un autre nom de ce programme est test:

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

Cela ressemble à la grammaire du shell mais ne l'est pas. Il [s'agit généralement d' un shell intégré, mais probablement comme solution de repli, il existe en tant que commande externe.

Voir le bloc "EXPRESSIONS CONDITIONNELLES" dans man bash.

Hauke ​​Laging
la source
9

[est la même commande que test. Sur certains systèmes * nix, l'un n'est qu'un lien vers l'autre. Par exemple, si vous exécutez:

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

vous verrez la même sortie.

La plupart des sh-shells / posix-shells incluent des commandes intégrées [et des testcommandes. Il en va de même pour echo. Il existe à la fois une /bin/echocommande et une fonction intégrée dans la plupart des obus. C'est la raison pour laquelle parfois vous sentez que, par exemple, echone fonctionne pas de la même manière sur différents systèmes.

testou [renvoyer uniquement un code de sortie de 0ou 1. Si le test a réussi, le code de sortie est 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

Vous pouvez également utiliser [avec 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

Mais vous pouvez utiliser ifavec chaque commande, ifpour tester le code de sortie. Par exemple:

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

Ou en utilisant if:

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

Vous pouvez obtenir le même résultat en utilisant uniquement la testcommande pour tester le code de sortie qui est enregistré dans la variable 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

Vous pouvez également utiliser [[ ]]et (( ))pour les tests, mais ceux-ci ne sont pas identiques à [et test, bien qu'ils aient presque la même syntaxe:

Enfin, pour découvrir ce qu'est une commande, vous pouvez utiliser:

type -a command
kshji
la source
Pour comparer des fichiers, vous devriez plutôt utiliser cmp /usr/bin/[ /usr/bin/testou peut-être des hachages sha256sum /usr/bin/[ /usr/bin/testmais pas strings. Sur mon système (openSUSE Tumbleweed) BTW ils ne sont pas les mêmes (pourquoi).
Hauke ​​Laging du
Je ne voulais pas comparer les octets. Dans certains * nix, ils sont identiques également en niveau d'octet = lié. Test Posix
kshji