Sempre fico surpreso que na pasta /bin
exista um [
programa.
É assim que se chama quando estamos fazendo algo como if [ something ]
:?
Ao chamar o [
programa explicitamente em um shell, ele solicita uma correspondência ]
e, quando eu forneço o colchete de fechamento, ele parece não fazer nada, não importa o que eu insira entre os colchetes.
Desnecessário dizer que a maneira usual de obter ajuda sobre um programa não funciona, ou seja, man [
nem [ --help
funciona.
[
refere-se aotest
comando, porém, nãoexpr
, assim que deve serman test
man '['
funciona bem para mim - ou você esqueceu de citar[
ou tem uma definição diferente de "funciona".[
avalia seus argumentos, portanto, você precisa ter espaços entre todos eles.[ a=b ]
não é uma comparação: sempre será verdadeira (é uma única sequência: "a = b", que é sempre avaliada como verdadeira ) E você deve limitar o número de argumentos a 4 (mesmo que implementações recentes permitam mais .. por exemplo, limita a 4, por exemplo:[ "a" = "b" ]
já possui 4 argumentos: "a" "=" "b" e o final desnecessário do teste arg: "]"). Se você precisar de mais: testes em cadeia com, por exemplo:if [ "$Var_a" = "foo" ] && [ "$Var_b" = "bar" ] ; then : do something ; fi
!
por si só (sem escape e sem aspas) não será substituído, e melhor aindaif ! [ ...
. Todas as expansões festança que usam!
incluir pelo menos em outro personagem[
-builtinbash
(e possivelmente outros reservatórios), e que isso pode ser usado em vez de/bin/[
. Também existe otest
comando-, que em muitos sistemas é um link simbólico para/bin/[
(ou vice-versa) - mas em outros é um comando separado.Respostas:
O
[
trabalho do comando é avaliar expressões de teste. Ele retorna com um status de saída 0 (que significa verdadeiro ) quando a expressão é resolvida como verdadeira e outra coisa (que significa falsa ) caso contrário.Não é que não faça nada, é apenas que seu resultado pode ser encontrado em seu status de saída. Em um shell, você pode descobrir sobre o status de saída do último comando em
$?
shells semelhantes a Bourne ou$status
na maioria dos outros shells (fish / rc / es / csh / tcsh ...).Em outros idiomas
perl
, o status de saída é retornado, por exemplo, no valor de retorno desystem()
:Observe que todos os shells modernos do tipo Bourne (e
fish
) possuem um[
comando interno. Aquele em/bin
que normalmente seria executado somente quando você usa outro shell ou quando faz coisas comoenv [ foo = bar ]
oufind . -exec [ -f {} ] \; -print
ou queperl
comandam acima ...O
[
comando também é conhecido pelotest
nome. Quando chamado comotest
, não requer um]
argumento de fechamento .Embora seu sistema possa não ter uma página de manual
[
, provavelmente tem uma paratest
. Mas, novamente, nota que seria documentar a/bin/[
ou/bin/test
implementação. Para saber sobre o[
built-in no seu shell, você deve ler a documentação do seu shell.Para obter mais informações sobre o histórico desse utilitário e a diferença com a
[[...]]
expressão de teste ksh, dê uma olhada nessas outras perguntas e respostas aqui .fonte
[
. Não me lembro se era uma variante Bourne ou uma versão antiga do ash.[
etest
como builtins com Unix System III. Antes disso, não havia[
etest
havia apenas um comando binário externo.find . -exec [ f {} ] \; -print
? O comandofind . -type f -print
faria a mesma coisa com muito mais eficiência ...Você está certo em ser surpreendido. Esse é um dos raros comandos POSIX, com o utilitário nulo (
:
), que não respeita a convenção de caracteres permitidos do arquivo de comandos (conjunto de caracteres do nome do arquivo portátil).Precisamente, mas pode ser usado sem o
if
também.Ele não faz nada visível, mas na verdade faz a mesma coisa do que quando usado
if
, ou seja, define o status de saída como 0 (verdadeiro) ou qualquer outra coisa (falso), dependendo do que você coloca dentro dos colchetes. É (por uma razão) o mesmo comportamento que otest
comando; a única diferença é que ele procura o final]
. Vejaman test
para detalhes.Isso depende do seu sistema operacional.
man [
definitivamente funciona para mim em algumas distribuições principais do Gnu / Linux, mas não no Solaris.[ --help
pode funcionar ou não, dependendo da implementação, pois está quebrando a sintaxe de qualquer maneira, perdendo o final]
. Além disso, o padrão POSIX para otest
/[
comando exclui explicitamente todas as opções, incluindo a--
rescisão opção para ambos[ --help ]
etest --help
necessidade de voltartrue
e ficar em silêncio por design. Note-se que o que você colocar dentro dos colchetes ou depois[
e que parecem opções (por exemplo-f file
,-n string
e os gostos) não são opções , mas operandos .Todos os intérpretes de shell estilo moderno Bourne (como
bash
,ksh
,dash
ezsh
para citar alguns) implementar otest
/[
utilidade internamente como um builtin assim quando você usá-los, a página do manual para a direita para se referir pode ser o único do shell, e não atest
um.Antes do Unix System III (1981), o shell Bourne não implementava o
test
utilitário como um componente interno; portanto, apenas a implementação do comando binário externo estava disponível. Não havia um[
comando (interno ou interno) até o Unix System III; por exemplo, no Unix Versão 7, você tinha que digitar:ao invés de:
fonte
man test
funciona, mas nãoman [
Por outro lado, meu ambiente cygwin conheceman [
!man [
parece não funcionar no Manjaro (baseado no Arch Linux). O manual paratest
listas[ --help
como uma invocação válida que deve mostrar ajuda, mas, curiosamente, não, e queixa-se de uma falta]
, o mesmo que com--version
. Adicionando o]
não faz nada, por isso parece impossível obter ajuda diferente deman test
./usr/bin/[ --help
ou/bin/[ --help
.env [ --help
além de/usr/bin/[ --help
funcionar completamente bem (embora eu precise citar/usr/bin/[
ou zsh reclamar).[
é realmente mais conhecido comotest
comando. O uso típico desse comando é simplesmente avaliar expressões e retornar sua condição - verdadeira ou falsa. É frequentemente usado emif-then-else-fi
instruções, embora possa ser usado fora dasif
instruções para executar condicionalmente outros comandos por meio de shell&&
ou||
operadores, assim.Mais especificamente, a avaliação é comunicada a outros comandos via status de saída. Alguns programas podem optar por emitir o status de saída para significar diferentes tipos de eventos - conclusão do programa com êxito, um erro de tipo específico ocorrendo durante a execução ou erros de sintaxe. No caso do
test
comando, existem0
significa verdadeiro e1
falso. Como apontou Stephan, os erros de sintaxe produzem o status de saída de2
.Sua localização depende do seu sistema e também explica por que você não viu a página de manual quando o viu
man [
. Por exemplo, no FreeBSD está abaixo/bin
. No Linux (ou no meu caso em particular, Ubuntu 16.04), ele está dentro/usr/bin/
. Se você fazman [
ouman test
em um sistema Linux, verá a mesma documentação aberta. Também é importante observar que seu shell pode ter sua própria implementaçãotest
.Também deve ser observado que esse comando tem problemas que a implementação do shell Korn (comumente conhecida como referência de "expressão condicional" com colchetes duplos
[[ "$USER" = "root" ]]
)) procura resolver. Esse recurso também é usado por outros shells, comobash
ezsh
.fonte
/usr/bin/
para o Amazon Linux também.Em algumas distros (por exemplo, Ubuntu),
man [
segue um link simbólico paratest(1)
. Em outros (por exemplo, Arch), este não é o caso. (Mas atest
página do manual também documenta o uso[
)type -a [
mostra que há um shell embutido e um executável.bash-builtin
[ --help
apenas imprime uma mensagem de erro. (Mas como é um builtin, você pode usarhelp [
ou consultar a página de manual do bash / docs)./usr/bin/[ --help
imprime a saída completa da ajuda (para a versão GNU Coreutils), que começa com:e, em seguida, descreve a sintaxe permitida para EXPRESSION.
Essa é outra maneira de descobrir isso
[
etest
ser equivalente.BTW, se você está programando para bash (ou escrevendo one-liners interativamente), eu recomendaria em
[[
vez de[
. É melhor de várias maneiras, veja os links na resposta de Serg.fonte
[
O comando retorna status de saída zero se a expressão contida em seus argumentos for considerada verdadeira e status de saída diferente de zero se expressão contida em seus argumentos for considerada falsa. Ele também falha com a mensagem de erro se seu último argumento não for]
(isso é feito puramente por razões estéticas).Por exemplo:
… Produzirá:
No entanto, o bash e muitos outros shells geralmente não invocam
/bin/[
(ou/usr/bin/[
) nesses casos, mas chamam o comando interno com exatamente o mesmo comportamento (apenas por razões de desempenho). Para chamar/bin/[
(não o substituto interno do shell), é necessário especificar explicitamente seu caminho (por exemplo/bin/[ hello ]
, você não precisa prefixar o nome do]
diretório embora ☺ ) ou configurar o shell para não usar um substituto interno (por exemplo,enable -n [
na festança).PS: Como foi dito em outras respostas,
[
está relacionado atest
. Mastest
, diferentemente[
, não exige]
como seu último argumento (e não o espera; adicionar acréscimos]
atest
argumentos pode causar falhas na mensagem de erro ou retornar resultados incorretos) . O/bin/test
e/bin/[
pode resolver para o mesmo arquivo (por exemplo, um está vinculado ; nesse caso, o desvio de comportamento provavelmente é implementado pela análise do comando atualmente chamado no próprio códigotest
/[
) ou para arquivos diferentes. Paratest
, o shell também geralmente chama substituto interno, a menos que o caminho seja especificado explicitamente (/bin/test
) ou esteja configurado para não fazer isso (enable -n test
)PPS: Ao contrário
test
e[
, modernoif
não é um arquivo real. Faz parte da sintaxe do shell (por exemplo, bash):if commandA; then commandB; fi
(novas linhas podem ser usadas em vez de ponto e vírgula) fazcommandB
com que seja executado se e somente se forcommandA
encerrado com status zero. Isso se encaixa perfeitamente ao comportamento detest
ou[
, permitindo combiná-los comoif [ "$a" = foo ]; then …; fi
(ouif test "$a" = foo; then …; fi
- apenas menos legíveis) . No entanto, scripts modernos costumam usar em[[
vez detest
ou[
, o que (comoif
) nunca é um arquivo real, mas sempre faz parte da sintaxe do shell.PPPS: Quanto a
man
- nunca espereman
ter um artigo sobre todos os comandos do seu sistema de arquivos. Informações sobre algumas informações (mesmo "real",-file com base) comandos podem estar faltando, em alguns shell built-ins talvez presente não só dentro de um artigo dedicado a shell específico (que é o lugar onde você certamente vai encontrar informações sobretest
,[
,if
,[[
). Ainda assim, muitas distribuições têm artigos explícitosman
paratest
e[
. (Sobre--help
, não é reconhecidotest
por uma razão óbvia: ele precisa lidar com casos silenciosos comoa=--help; test "$a"
; em algumas distribuições[ --help
(sem fechar]
) ainda mostra ajuda, em outras não).fonte
if
foi um comando até o Unix V6. O Unix V7 (1979) veio com o shell Bourne (com suaif-then-else-fi
construção) e o novotest
comando.