O que os colchetes significam sem o "if" à esquerda? [duplicado]

43

Até onde eu sei, os colchetes são usados para delimitar uma expressão normalmente em if more statements.

Mas encontrei colchetes sendo usados sem o "if" da seguinte forma:

[ -r /etc/profile.d/java.sh ] && . /etc/profile.d/java.sh

no seguinte script.

#!/bin/bash### BEGIN INIT INFO  
# Provides:          jbossas7  
# Required-Start:    $local_fs $remote_fs $network $syslog  
# Required-Stop:     $local_fs $remote_fs $network $syslog  
# Default-Start:     2 3 4 5  
# Default-Stop:      0 1 6  
# Short-Description: Start/Stop JBoss AS 7  
### END INIT INFO  
# chkconfig: 35 92 1  

## Include some script files in order to set and export environmental variables  
## as well as add the appropriate executables to $PATH.  
[ -r /etc/profile.d/java.sh ] && . /etc/profile.d/java.sh  
[ -r /etc/profile.d/jboss.sh ] && . /etc/profile.d/jboss.sh  

JBOSS_HOME=/sw/AS7  

AS7_OPTS="$AS7_OPTS -Dorg.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0=true"   ## See AS7-1625  
AS7_OPTS="$AS7_OPTS -Djboss.bind.address.management=0.0.0.0"  
AS7_OPTS="$AS7_OPTS -Djboss.bind.address=0.0.0.0"  

case "$1" in  
    start)  
        echo "Starting JBoss AS 7..."  
        #sudo -u jboss sh ${JBOSS_HOME}/bin/standalone.sh $AS7_OPTS           ##  If running as user "jboss"  
        #start-stop-daemon --start --quiet --background --chuid jboss --exec ${JBOSS_HOME}/bin/standalone.sh $AS7_OPTS   ## Ubuntu  
        ${JBOSS_HOME}/bin/standalone.sh $AS7_OPTS &  
    ;;  
    stop)  
        echo "Stopping JBoss AS 7..."  
        #sudo -u jboss sh ${JBOSS_HOME}/bin/jboss-admin.sh --connect command=:shutdown            ##  If running as user "jboss"  
        #start-stop-daemon --start --quiet --background --chuid jboss --exec ${JBOSS_HOME}/bin/jboss-admin.sh -- --connect command=:shutdown     ## Ubuntu  
        ${JBOSS_HOME}/bin/jboss-cli.sh --connect command=:shutdown  
    ;;  
    *)  
        echo "Usage: /etc/init.d/jbossas7 {start|stop}"; exit 1;  
    ;;  
esac  

exit 0  

O que os colchetes fazem sem o "if"? Quero dizer, exatamente, o que eles significam quando usados nesse contexto?

Esta não é uma cópia de que na qual o OP usado "se" com o qual não tenho problema. Nesta questão, os colchetes foram usados de maneira intuitiva. Essa pergunta e essa pergunta podem ter a mesma resposta, mas são duas perguntas diferentes.

    
por supertonsky 07.11.2013 / 08:58

2 respostas

56

Os colchetes são uma notação abreviada para realizar um teste condicional. Os colchetes [ , bem como [[ são comandos reais dentro do Unix, acredite ou não.

Pense:

$ [ -f /etc/rc.local ] && echo "real file"
real file

-and-

$ test -f /etc/rc.local && echo "real file"
real file

No Bash, o [ é um comando interno, assim como um executável. [[ é apenas uma palavra-chave para o Bash.

Exemplo

Você pode confirmar isso usando type :

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

$ type -a [[
[[ is a shell keyword

Você pode ver o executável físico aqui:

$ ls -l /usr/bin/[
-rwxr-xr-x 1 root root 37000 Nov  3  2010 /usr/bin/[

builtins vs. keywords

Se você der uma olhada na página man do Bash, man bash , você encontrará as seguintes definições para o 2:

  • palavras-chave - Palavras reservadas são palavras que têm um significado especial para o shell. As seguintes palavras são reconhecidas como reservadas quando não mencionadas e a primeira palavra de um comando simples (consulte SHELL GRAMMAR abaixo) ou a terceira palavra de um caso ou comando:

    ! case  do done elif else esac fi for function if in select then until while { } time [[ ]]
    
  • builtins - Se o nome do comando não contiver barras, o shell tentará localizá-lo. Se existe uma função de shell com esse nome, essa função é invocada como descrito acima em FUNÇÕES. Se o nome não corresponder a uma função, o shell a procurará na lista de built-ins do shell. Se uma correspondência for encontrada, esse builtin é invocado.

    Se o nome não for nem uma função do shell nem um builtin e não contiver barras, o bash pesquisará cada elemento do PATH em um diretório que contenha um arquivo executável com esse nome. O Bash usa uma tabela de hash para lembrar os nomes completos dos arquivos executáveis (veja o hash em SHELL BUILTIN COMMANDS abaixo). Uma pesquisa completa dos diretórios no PATH é executada somente se o comando não for encontrado na tabela de hash. Se a pesquisa não for bem-sucedida, o shell procurará uma função de shell definida denominada command_not_found_handle. Se essa função existir, ela é invocada com o comando original e os argumentos do comando original como seus argumentos, e o status de saída da função se torna o status de saída do shell. Se essa função não estiver definida, o shell imprimirá uma mensagem de erro e retornará um status de saída de 127.

man page

Se você examinar a página do manual do Bash, encontrará os detalhes.

test expr
[ expr ]
          Return a status of 0 or 1 depending on the evaluation of the 
          conditional expression expr.  Each operator and operand must be
          a separate argument.  Expressions are composed of the  primaries 
          described  above  under  CONDITIONAL EXPRESSIONS.   test does not 
          accept any options, nor does it accept and ignore an argument of 
          -- as signifying the end of options.

Por fim, na página do manual:

          test and [ evaluate conditional expressions using a set of rules
          based on the number of arguments.

EDIT # 1

Pergunta de acompanhamento do OP.

Ok, so why is there a need for an "if" then? I mean, why "if" even exists if "[" would suffice.

O if faz parte de um condicional. O comando test ou [ ... ] simplesmente avalia o condicional e retorna um 0 ou um 1. O 0 ou 1 é então acionado pela instrução if. Os 2 estão trabalhando juntos quando você os usa.

Exemplo

if [ ... ]; then
   ... do this ...
else 
   ... do that ...
fi
    
por 07.11.2013 / 09:08
26

Ooohh, um dos meus tópicos favoritos !!

Os colchetes são um sinônimo para o comando "teste". Se você ler a man page do teste, verá que pode invocar o comando test como

test -r /etc/profile.d/java.sh

ou

[ -r /etc/profile.d/java.sh ]

Os espaços entre os parênteses e as coisas dentro e fora deles são obrigatórios.

O comando "test", neste caso, está verificando se o arquivo /etc/profile.d/java.sh é legível para o usuário atual. Implícito é um cheque para ver se existe, é claro. : -)

O & & é o atalho bash para "se o comando à esquerda for bem-sucedido, então execute o comando à direita. Então, este composto comanda um atalho para ele e se ele ficaria assim:

if test -r /etc/profile.d/java.sh
then
  /etc/profile.d/java.sh
fi

Agora, você também encontrará colchetes duplos explicados na man page bash. Essas são uma versão interna bash de uma função de teste estendida. Esteja ciente de que esses não são exatamente os mesmos. Há coisas que você pode fazer com aquelas que você não pode fazer com o comando "test" e é "[" sinônimo ".

    
por 07.11.2013 / 09:15

Tags