根据引用类型对 ~/.bash_profile 别名中的 pwd 进行不同评估

Eko*_*pha 2 macos shell alias osx-elcapitan

这是在 OSX El Capitan 上,但也发生在我的 Ubuntu 别名中。

我遇到了一个问题,我创建的别名将工作目录传递给 docker 容器。

这将不起作用(无论我在哪个目录中,始终为 $(pwd) 传递 ~/Users/username ):

alias phpqa="docker run --rm -u $UID -v $(pwd):/app eko3alpha/docker-phpqa"
Run Code Online (Sandbox Code Playgroud)

作品:

alias phpqa='docker run --rm -u $UID -v $(pwd):/app eko3alpha/docker-phpqa'
Run Code Online (Sandbox Code Playgroud)

但是,当传入错误的路径时,我的脚本中开始出现意外错误。所以我做了一个实验。我将这两个别名添加到我的 ~/.bash_profile 中。

alias getpath="echo $(pwd)"
alias getpath2='echo $(pwd)'
Run Code Online (Sandbox Code Playgroud)

我注销然后重新登录。

更改目录:

$ cd /Users/username/correct/path/to/project
Run Code Online (Sandbox Code Playgroud)

执行两个别名:

$ getpath
/Users/username

$ getpath2
/Users/username/correct/path/to/project
Run Code Online (Sandbox Code Playgroud)

带双引号的别名总是返回用户主目录,而带单引号的别名返回当前目录。有人可以解释为什么会这样吗?

Gil*_*il' 5

别名定义像任何其他命令一样被解析。在双引号内,扩展了$UID诸如变量替换和命令替换之类$(pwd)的内容。在单引号内,没有展开任何内容:唯一的特殊字符是终止单引号文字的单引号。

alias phpqa="docker run --rm -u $UID -v $(pwd):/app eko3alpha/docker-phpqa"
Run Code Online (Sandbox Code Playgroud)

假设您的用户 ID 是 1000 并且当前目录是您读取/Users/username时的主目录.bash_profile,这定义phpqa了扩展名为docker run --rm -u 1000 -v /Users/username:/app eko3alpha/docker-phpqa.

alias phpqa='docker run --rm -u $UID -v $(pwd):/app eko3alpha/docker-phpqa'
Run Code Online (Sandbox Code Playgroud)

这定义了phpqa带有扩展名的别名docker run --rm -u $UID -v $(pwd):/app eko3alpha/docker-phpqa。每次扩展别名时,它都会被相应的字符串替换,并且该字符串受通常的 shell 解析规则的约束。所以每次使用别名时,都会使用变量的当前值UIDpwd执行命令。

这个别名的正确定义是

alias phpqa='docker run --rm -u "$UID" -v "$PWD:/app" eko3alpha/docker-phpqa'
Run Code Online (Sandbox Code Playgroud)

始终在变量和命令替换周围使用双引号,除非您知道需要省略它们$PWD并且$(pwd)是等价的(shell 跟踪变量中的当前目录PWD)。

或者,忘记引用(替换周围的双引号除外)并使用函数。

phpqa () {
  docker run --rm -u "$UID" -v "$PWD:/app" eko3alpha/docker-phpqa "$@"
}
Run Code Online (Sandbox Code Playgroud)