O que significa $ {PATH: +: $ {PATH}}?

21

Recentemente, observei o seguinte no meu perfil do cygwin, mais precisamente:

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

O que isso significa? Por que não é apenas $ PATH? É este um 'se $ PATH existe então adicione: $ PATH'? Meu objetivo é trocar a ordem e colocar os caminhos do cygwin atrás do caminho das janelas. No passado eu teria

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

mas isso me confunde. Talvez eu devesse estar fazendo

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

para anexar o: no final do $ PATH?

    
por tofutim 04.03.2016 / 00:04

2 respostas

35

O :+ é uma forma de expansão de parâmetros :

${parameter:+[word]} : Use Alternative Value.

If parameter is unset or null, null shall be substituted; otherwise, the expansion of word (or an empty string if word is omitted) shall be substituted.

Em outras palavras, se a variável $var for definida, echo ${var:+foo} imprimirá foo e, se não for, imprimirá a string vazia.

O segundo : não é nada especial. É o caractere usado como um separador na lista de diretórios em $PATH . Então, PATH="/usr/local/bin:/usr/bin${PATH:+:${PATH}}" é uma forma abreviada de escrever:

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

É apenas um truque inteligente para evitar adicionar um : extra quando $PATH não está definido. Por exemplo:

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

Mas se PATH não estiver definido:

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

Um : por si só adiciona o diretório atual ao $PATH . Usar PATH="/new/dir${PATH:+:$PATH}" evita isso. Então, você pode usar PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin" se quiser, ou você pode usar PATH="$PATH:/usr/local/bin:/usr/bin" se preferir. A única diferença é que o primeiro pode adicionar um : extra, adicionando assim seu diretório atual ao seu $PATH .

    
por 04.03.2016 / 00:29
8

Você está correto, significa 'se $ PATH existe - e não é nulo - então adicione: $ PATH'.

Você precisa verificar se o $ PATH existe porque você não deseja adicionar o cólon inicial (ou posterior) se $ PATH estiver indefinido. Um nome de diretório com comprimento zero (nulo) no caminho, como em :/usr/local/bin:/usr/bin ou /usr/local/bin:/usr/bin: ou /usr/local/bin::/usr/bin , significa que pesquisa o diretório atual .

Extraído 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.
          ...

Isso provavelmente não é o que você quer fazer.

As duas linhas seguintes fazem a mesma coisa:

PATH=":/bin"        # search current directory, then /bin
PATH=".:/bin"
    
por 04.03.2016 / 07:28