Que signifie $ {PATH: +: $ {PATH}}?

25

J'ai récemment remarqué ce qui suit dans mon profil cygwin, plus précisément:

/usr/local/bin:/usr/bin${PATH:+:${PATH}}

Qu'est-ce que ça veut dire? Pourquoi n'est-il pas seulement $ PATH? S'agit-il d'un 'si $ PATH existe alors ajoutez: $ PATH'? Mon but est d'échanger la commande et de mettre les chemins cygwin derrière le chemin Windows. Dans le passé, j'aurais

$PATH:/usr/local/bin:/usr/bin

mais cela me confond. Peut-être que je devrais faire

PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin"

ajouter le: à la fin du $ PATH?

tofutim
la source
1
Le titre de votre question a vraiment gâché la mise en forme dans la barre latérale SE Hot Questions i.imgur.com/g6pPmzf.png
Brad

Réponses:

39

Le :+est une forme d' expansion des paramètres :

$ {paramètre: + [mot]} : utilisez une valeur alternative.

Si le paramètre est non défini ou nul, null doit être remplacé; sinon, l'expansion de mot (ou une chaîne vide si mot est omis) doit être remplacée.

En d'autres termes, si la variable $varest définie, echo ${var:+foo}sera imprimée fooet, si ce n'est pas le cas, elle imprimera la chaîne vide.

Le second :n'a rien de spécial. Il s'agit du caractère utilisé comme séparateur dans la liste des répertoires de $PATH. Donc, PATH="/usr/local/bin:/usr/bin${PATH:+:${PATH}}"c'est une façon abrégée d'écrire:

if [ -z "$PATH" ]; then
    PATH=/usr/local/bin:/usr/bin
else
    PATH=/usr/local/bin:/usr/bin:$PATH
fi

C'est juste une astuce astucieuse pour éviter d'ajouter un supplément :quand il $PATHn'est pas défini. Par exemple:

$ PATH="/usr/bin"
$ PATH="/new/dir:$PATH" ## Add a directory
$ echo "$PATH"
/new/dir:/usr/bin

Mais si PATHn'est pas défini:

$ unset PATH
$ PATH="/new/dir:$PATH"
$ echo "$PATH"
/new/dir:

A :ajoute lui-même le répertoire courant au $PATH. L'utilisation PATH="/new/dir${PATH:+:$PATH}"évite cela. Alors bien sûr, vous pouvez utiliser PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin"si vous le souhaitez, ou vous pouvez utiliser PATH="$PATH:/usr/local/bin:/usr/bin"si vous préférez. La seule différence est que le premier peut ajouter un extra :, ajoutant ainsi votre répertoire actuel à votre $PATH.

terdon
la source
L'extra :nuisible?
cat
4
@tac pas vraiment, il ajoute simplement le répertoire courant à votre $PATH(voir la réponse de @ AndyB ). Cela peut être un risque pour la sécurité dans certaines situations (par exemple, un attaquant a téléchargé un script destructeur dans votre répertoire actuel et l'a nommé lsou quelque chose), mais dans la plupart des cas, cela ne vous dérange pas vraiment. En fait, certains systèmes ajoutent PATHquand même le répertoire courant au par défaut.
terdon
le chemin est le seul endroit où je préférerais qu'ils le cshgèrent comme un tableau.
hometoast
8

Vous avez raison, cela signifie «si $ PATH existe - et n'est pas nul - alors ajoutez: $ PATH».

Vous devez vérifier si $ PATH existe parce que vous ne voulez pas ajouter le signe deux-points de tête (ou de fin) si $ PATH n'est pas défini. Un nom de répertoire de longueur nulle (null) dans le chemin, comme dans :/usr/local/bin:/usr/bin, ou /usr/local/bin:/usr/bin:, ou /usr/local/bin::/usr/bin, signifie rechercher dans le répertoire actuel .

Extrait de man bash:

   PATH   ...
          A zero-length (null) directory name in the value of PATH indicates 
          the current directory.  A  null  directory name may appear as two 
          adjacent colons, or as an initial or trailing colon.
          ...

Ce n'est probablement pas ce que vous voulez faire.

Les deux lignes suivantes font la même chose:

PATH=":/bin"        # search current directory, then /bin
PATH=".:/bin"
AndyB
la source