¿Cuál es el propósito del ejecutable de corchetes

27

Veo que hay un ejecutable llamado "[" en /usr/bin. ¿Cual es su propósito?

ingrese la descripción de la imagen aquí

Alexandru Irimiea
fuente

Respuestas:

33

En la mayoría de los casos, [es una concha incorporada y es equivalente a test. Sin embargo, como test, también existe como un ejecutable independiente: eso es lo /bin/[que viste. Puede probar esto con type -a [(en un sistema Arch Linux, en ejecución bash):

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

Entonces, en mi sistema, tengo dos [: mi shell está integrado y el ejecutable en /bin. El ejecutable está documentado en 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.

[ ... ]

Como se puede ver en el extracto de la página del manual citado anteriormente, testy [son equivalentes. El /bin/[y /bin/testcomandos se especifica por POSIX razón por la cual los encontrará a pesar del hecho de que muchas conchas también les proporcionan como órdenes internas. Su presencia asegura que construcciones como:

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

funcionará incluso si el shell que los ejecuta no tiene [incorporado. Por ejemplo, en tcsh:

> which [
/sbin/[
> set var = 11
> [ "$var" -gt 10 ]  && echo yes
yes
terdon
fuente
55
@AlexandruIrimiea, ¿qué quieres decir? Un shell que no tiene el [builtin incorporado es solo un shell cuyos autores decidieron no agregar uno. tcsh no tiene un [incorporado por ejemplo.
terdon
77
@AlexandruIrimiea no son conchas "personalizadas". Es solo que bashes uno de los muchos programas (shells) que están diseñados para hacer trabajos similares. Bash es uno de los más populares, pero muchos sistemas se envían con diferentes shells predeterminados. Algunos de los más conocidos son sh, bash, zsh, dash, ksh, tcsh, cshy fish. Puede ver los disponibles en su sistema cat /etc/shellsy una lista parcial aquí .
terdon
1
@ JörgWMittag realmente? Sabía que Ubuntu shes, dashpero pensé que el sistema de rescate /bin/shno usa busybox. ¿Estás seguro?
terdon
2
Sin embargo, de hecho, hay una caja ocupada en initramfs, como lo demuestra esta pregunta
Sergiy Kolodyazhnyy
1
@AlexandruIrimiea, con respecto a qué comandos es necesario tener incorporado y qué comandos pueden o no estar integrados, vea esta publicación .
Comodín el
12

Eso se usa para pruebas de condición en scripts de shell. Otro nombre de este programa es test:

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

Eso parece una gramática de shell pero no lo es. Por [lo general, es un shell incorporado, pero probablemente como respaldo existe como un comando externo.

Ver el bloque "EXPRESIONES CONDICIONALES" en man bash.

Hauke ​​Laging
fuente
9

[es el mismo comando que test. En algunos sistemas * nix, uno es solo un enlace al otro. Por ejemplo, si ejecuta:

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

verá la misma salida.

La mayoría de los sh-shells / posix-shells incluyen builtin [y testcomandos. Lo mismo es cierto para echo. Hay un /bin/echocomando y un incorporado en la mayoría de los proyectiles. Esa es la razón por la que a veces sientes que, por ejemplo, echono funciona de la misma manera en diferentes sistemas.

testo [devolver solo un código de salida de 0o 1. Si la prueba fue exitosa, el código de salida es 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

También puedes usar [con 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

Pero puede usarlo ifcon cada comando, ifes para probar el código de salida. Por ejemplo:

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

O, usando if:

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

Puede obtener el mismo resultado utilizando solo el testcomando para probar el código de salida que se guarda en 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

También puede usar [[ ]]y (( ))para probar, pero no son lo mismo que [y test, a pesar de tener casi la misma sintaxis:

Finalmente, para descubrir qué es un comando, puede usar:

type -a command
kshji
fuente
Para comparar archivos, debería usar cmp /usr/bin/[ /usr/bin/testo quizás hash sha256sum /usr/bin/[ /usr/bin/testpero no strings. En mi sistema (openSUSE Tumbleweed), por cierto, no son lo mismo (whyever).
Hauke ​​Laging
No quise comparar bytes. En algunos * nix son iguales también en byte level = enlazado. Prueba Posix
kshji