web-dev-qa-db-fra.com

Que signifient les crochets sans le "si" à gauche?

Pour autant que je sache, les crochets sont utilisés pour entourer une expression généralement dans les instructions if else.

Mais j'ai trouvé des crochets utilisés sans le "si" comme suit:

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

dans le script suivant.

#!/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  

Que font les crochets sans le "si"? Je veux dire, exactement, que signifient-ils lorsqu'ils sont utilisés dans ce contexte?

Ce n'est pas un doublon de that dans lequel l'OP a utilisé "if" avec lequel je n'ai aucun problème. Dans cette question, les parenthèses ont été utilisées de manière contre-intuitive. Cette question et cette question peuvent avoir la même réponse mais ce sont deux questions différentes.

59
supertonsky

Les crochets sont une notation abrégée pour effectuer un test conditionnel. Les crochets [, Ainsi que [[ Sont des commandes réelles dans Unix, croyez-le ou non.

Pense:

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

-and-

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

Dans Bash, le [ Est une commande intégrée ainsi qu'un exécutable. [[ N'est qu'un mot-clé pour Bash.

Exemple

Vous pouvez le confirmer en utilisant type:

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

$ type -a [[
[[ is a Shell keyword

Vous pouvez voir l'exécutable physique ici:

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

builtins vs mots clés

Si vous jetez un œil à la page de manuel de Bash, man bash, Vous trouverez les définitions suivantes pour le 2:

  • mots-clés - Les mots réservés sont des mots qui ont une signification particulière pour le Shell. Les mots suivants sont reconnus comme réservés lorsqu'ils ne sont pas entre guillemets et soit le premier mot d'une commande simple (voir Shell GRAMMAR ci-dessous), soit le troisième mot d'un cas ou d'une commande:

    ! case  do done Elif else esac fi for function if in select then until while { } time [[ ]]
    
  • builtins - Si le nom de la commande ne contient aucune barre oblique, le shell tente de le localiser. S'il existe une fonction Shell portant ce nom, cette fonction est appelée comme décrit ci-dessus dans FONCTIONS. Si le nom ne correspond pas à une fonction, le shell le recherche dans la liste des commandes internes du shell. Si une correspondance est trouvée, cette fonction intégrée est invoquée.

    Si le nom n'est ni une fonction Shell ni une fonction intégrée, et ne contient pas de barres obliques, bash recherche dans chaque élément du PATH un répertoire contenant un fichier exécutable de ce nom. Bash utilise une table de hachage pour se souvenir des chemins d'accès complets des fichiers exécutables (voir hachage sous Shell BUILTIN COMMANDS ci-dessous). Une recherche complète des répertoires dans PATH n'est effectuée que si la commande n'est pas trouvée dans la table de hachage. Si la recherche échoue, le Shell recherche une fonction Shell définie nommée command_not_found_handle. Si cette fonction existe, elle est invoquée avec la commande d'origine et les arguments de la commande d'origine comme arguments, et l'état de sortie de la fonction devient l'état de sortie du Shell. Si cette fonction n'est pas définie, le shell imprime un message d'erreur et renvoie un état de sortie de 127.

man page

Si vous parcourez la page de manuel de Bash, vous y trouverez les détails.

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.

Enfin à partir de la page de manuel:

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

EDIT # 1

Question complémentaire du PO.

Ok, alors pourquoi faut-il un "si" alors? Je veux dire, pourquoi "si" existe même si "[" suffirait.

if fait partie d'un conditionnel. La commande test ou la commande [ ... ] Évalue simplement le conditionnel et renvoie un 0 ou un 1. Le 0 ou 1 est ensuite appliqué par l'instruction if. Les 2 travaillent ensemble lorsque vous les utilisez.

Exemple

if [ ... ]; then
   ... do this ...
else 
   ... do that ...
fi
70
slm

Ooohh, l'un de mes sujets préférés !!

Les crochets sont synonymes de la commande "test". Si vous lisez la page de manuel de test, vous verrez que vous pouvez appeler la commande test soit

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

ou

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

Les espaces entre les supports et les objets à l'intérieur et à l'extérieur sont nécessaires.

Dans ce cas, la commande "test" vérifie si le fichier /etc/profile.d/Java.sh est lisible par l'utilisateur actuel. Bien entendu, il s'agit d'une vérification pour voir si elle existe. :-)

Le && est un raccourci de syntaxe bash pour "si la commande de gauche réussit, puis exécutez la commande de droite. Donc, cette commande composée est un raccourci pour un" si-alors "qui ressemblerait à ceci:

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

Maintenant, vous trouverez également des crochets doubles expliqués dans la page de manuel bash. Il s'agit d'une version interne bash d'une fonction de test étendue. Sachez que ce ne sont pas exactement les mêmes. Il y a des choses que vous pouvez faire avec celles que vous ne pouvez pas faire avec la commande "test" et son synonyme "[".

30
Mike Diehn