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

24

Recentemente, notei 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? Isso é 'se $ PATH existir, adicione: $ PATH'? Meu objetivo é trocar a ordem e colocar os caminhos cygwin atrás do caminho do Windows. 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"

acrescentar o: no final do $ PATH?

tofutim
fonte
11
O título da sua pergunta realmente mexeu com a formatação na barra lateral do SE Hot Questions i.imgur.com/g6pPmzf.png
Brad

Respostas:

38

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

$ {parâmetro: + [word]} : use valor alternativo.

Se o parâmetro for desabilitado ou nulo, nulo será substituído; caso contrário, a expansão da palavra (ou uma sequência vazia, se a palavra for omitida) deve ser substituída.

Em outras palavras, se a variável $varfor definida, echo ${var:+foo}será impressa fooe, se não for, será impressa a sequência vazia.

O segundo :não é nada de 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 maneira 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 $PATHnão estiver definido. Por exemplo:

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

Mas se PATHnão estiver definido:

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

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

terdon
fonte
O extra é :prejudicial?
cat
4
@tac não, apenas adiciona o diretório atual ao seu $PATH(veja a resposta de @ AndyB ). Isso pode ser um risco de segurança em algumas situações (digamos que um invasor tenha carregado um script destrutivo no diretório atual e o tenha nomeado lsou algo assim), mas na maioria dos casos, você realmente não se importa. De fato, alguns sistemas adicionam o diretório atual ao PATHpadrão de qualquer maneira.
terdon
o caminho é o único lugar em que eu preferiria que eles lidassem cshcom isso como uma matriz.
hometoast 4/03/16
8

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

Você precisa verificar se $ PATH existe porque não deseja adicionar os dois pontos iniciais (ou à direita) se $ PATH estiver indefinido. Um nome de diretório de tamanho zero (nulo) no caminho, como em :/usr/local/bin:/usr/bin, ou /usr/local/bin:/usr/bin:, ou /usr/local/bin::/usr/bin, significa pesquisar no 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.
          ...

Provavelmente não é isso que você quer fazer.

As duas linhas a seguir fazem a mesma coisa:

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