Respostas:
Na maioria dos casos, [
é um shell embutido e é equivalente a test
. No entanto, test
também existe como um executável independente: foi o que /bin/[
você viu. Você pode testar isso com type -a [
(em um sistema Arch Linux, em execução bash
):
$ type -a [
[ is a shell builtin
[ is /bin/[
Portanto, no meu sistema, tenho dois [
: o shell está embutido e o executável no /bin
. O executável está documentado em 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 você pode ver no trecho da página homem citado acima, test
e [
são equivalentes. Os comandos /bin/[
e /bin/test
são especificados pelo POSIX, e é por isso que você os encontrará, apesar de muitos shells também os fornecerem como integrados. Sua presença garante que construções como:
[ "$var" -gt 10 ] && echo yes
funcionará mesmo se o shell que os executa não tiver um [
builtin. Por exemplo, em tcsh
:
> which [
/sbin/[
> set var = 11
> [ "$var" -gt 10 ] && echo yes
yes
bash
é apenas um dos muitos programas (shells) projetados para realizar tarefas semelhantes. O Bash é um dos mais populares, mas muitos sistemas são fornecidos com diferentes shells padrão. Alguns dos mais conhecidos são sh
, bash
, zsh
, dash
, ksh
, tcsh
, csh
e fish
. Você pode ver os disponíveis em seu sistema cat /etc/shells
e uma lista parcial aqui .
sh
é, dash
mas achei que o sistema de resgate /bin/sh
não usa o busybox. Você tem certeza?
Isso é usado para teste de condição em scripts de shell. Outro nome deste programa é test
:
if [ 1 -lt 2 ]; then ...
Parece gramática de shell, mas não é. Geralmente [
é um shell embutido, mas provavelmente como fallback existe como um comando externo.
Veja o bloco "EXPRESSÕES CONDICIONAIS" em man bash
.
[
é o mesmo comando que test
. Em alguns sistemas * nix, um é apenas um link para o outro. Por exemplo, se você executar:
strings /usr/bin/test
strings /usr/bin/[
você verá a mesma saída.
A maioria dos shells / posix-shells inclui builtin [
e test
comandos. O mesmo vale para echo
. Há um /bin/echo
comando e um builtin na maioria dos shells. Essa é a razão pela qual às vezes você sente que, por exemplo, echo
não funciona da mesma maneira em sistemas diferentes.
test
ou [
retorne apenas um código de saída de 0
ou 1
. Se o teste foi bem-sucedido, o código de saída é 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
Você também pode usar [
com 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
Mas você pode usar if
com todos os comandos, if
é para testar o código de saída. Por exemplo:
cp x y 2>/dev/null && echo cp x y OK || echo cp x y not OK
Ou, usando if
:
if cp x y 2>/dev/null ; then
echo cp x y OK
else
echo cp x y not OK
fi
Você pode obter o mesmo resultado usando apenas o test
comando para testar o código de saída que é salvo na variável 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
Você também pode usar [[ ]]
e (( ))
para testar, mas esses não são os mesmos [
e test
, apesar de terem quase a mesma sintaxe:
Por fim, para descobrir o que é um comando, você pode usar:
type -a command
cmp /usr/bin/[ /usr/bin/test
ou talvez hashes, sha256sum /usr/bin/[ /usr/bin/test
mas não strings
. No meu sistema (openSUSE Tumbleweed), aliás, eles não são os mesmos (por que razão).
[
builtin é apenas um shell cujos autores decidiram não adicionar um.tcsh
não tem um[
builtin, por exemplo.