${PATH:+:${PATH}} 是什么意思?

tof*_*tim 30 shell path variable-substitution

我最近在我的 cygwin 配置文件中注意到以下内容,更准确地说:

/usr/local/bin:/usr/bin${PATH:+:${PATH}}
Run Code Online (Sandbox Code Playgroud)

这是什么意思?为什么不只是 $PATH?这是“如果 $PATH 存在则添加:$PATH”吗?我的目的是交换顺序并将 cygwin 路径放在 windows 路径后面。过去我会

$PATH:/usr/local/bin:/usr/bin
Run Code Online (Sandbox Code Playgroud)

但这让我感到困惑。也许我应该做

PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin"
Run Code Online (Sandbox Code Playgroud)

追加 : 在 $PATH 的末尾?

ter*_*don 45

的:+是一种形式的参数扩展:

${parameter:+[word]}:使用替代值。

如果参数未设置或为空,则应替换为空;否则,应替换 word 的扩展(如果省略 word 则为空字符串)。

换句话说,如果$var定义了变量,echo ${var:+foo}将打印foo,如果没有,它将打印空字符串。

第二个:没什么特别的。它是在$PATH. 所以,PATH="/usr/local/bin:/usr/bin${PATH:+:${PATH}}"是一种速记方式:

if [ -z "$PATH" ]; then
    PATH=/usr/local/bin:/usr/bin
else
    PATH=/usr/local/bin:/usr/bin:$PATH
fi
Run Code Online (Sandbox Code Playgroud)

这只是一个聪明的技巧,可以避免:在$PATH未设置时添加额外的内容。例如:

$ PATH="/usr/bin"
$ PATH="/new/dir:$PATH" ## Add a directory
$ echo "$PATH"
/new/dir:/usr/bin
Run Code Online (Sandbox Code Playgroud)

但如果PATH未设置:

$ unset PATH
$ PATH="/new/dir:$PATH"
$ echo "$PATH"
/new/dir:
Run Code Online (Sandbox Code Playgroud)

A:本身将当前目录添加到$PATH. 使用PATH="/new/dir${PATH:+:$PATH}"可以避免这种情况。当然,您可以PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin"根据需要使用,也可以根据需要使用PATH="$PATH:/usr/local/bin:/usr/bin"。唯一的区别是前者可能会添加一个额外的:,从而将您当前的目录添加到您的$PATH.

  • @tac 不是真的,它只是将当前目录添加到您的“$PATH”(参见 @AndyB 的 [答案](http://unix.stackexchange.com/a/267548/22222))。在某些情况下,这可能是一个安全风险(假设攻击者已将破坏性脚本上传到您的当前目录并将其命名为 `ls` 或其他名称),但在大多数情况下,您真的不介意。事实上,有些系统无论如何都会默认将当前目录添加到“PATH”中。 (5认同)
  • 多余的`:`有害吗? (2认同)

And*_*dyB 9

你是对的,它的意思是“如果 $PATH 存在——并且不为空——然后添加:$PATH”。

您需要检查 $PATH 是否存在,因为如果 $PATH 未定义,您不想添加前导(或尾随)冒号。路径中的零长度(空)目录名,如:/usr/local/bin:/usr/bin、 or /usr/local/bin:/usr/bin:、 or /usr/local/bin::/usr/bin,表示搜索当前目录。

摘自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.
          ...
Run Code Online (Sandbox Code Playgroud)

这可能不是您想要做的。

以下两行做同样的事情:

PATH=":/bin"        # search current directory, then /bin
PATH=".:/bin"
Run Code Online (Sandbox Code Playgroud)