我在 zsh 和 bash 控制台中获得了以下函数别名:
compose() {
docker-compose $*
}
run() {
compose "run --rm app $*"
}
rails() {
run "rails $*"
}
在 bash 中,运行rails c
通过 docker-compose 成功启动 Ruby on Rails 控制台。
在 zsh 中,运行rails c
会导致命令未找到错误,其中连字符被下划线替换:
➜ rails c
No such command: run __rm app rails c
我的 zsh 版本:
➜ zsh --version
zsh 5.6.2 (x86_64-apple-darwin18.0.0)
答案1
这并不是zsh
用下划线替换破折号,而是可能是那个docker-compose
程序,或者它调用的另一个程序。
问题是zsh
,与 不同bash
,默认情况下不会拆分未加引号的变量IFS
。
如果我定义docker-compose
为一个函数,打印它的每个参数,包围起来{}
,这就是我得到的:
$ cat example
docker-compose() {
echo -n docker-compose
for f in "$@"; do echo -n " {$f}"; done; echo
}
compose() { docker-compose $*; }
run() { compose "run --rm app $*"; }
rails() { run "rails $*"; }
rails c
$ zsh example
docker-compose {run --rm app rails c}
$ bash example
docker-compose {run} {--rm} {app} {rails} {c}
run
请注意、--rm
、等如何app
作为单独的参数在 中传递,bash
以及如何作为单个参数传递zsh
。
这是因为确实使用空格( 的默认值)作为分隔符bash
将变量拆分并修剪为多个参数。通过使用代替或通过选项可以获得相同的效果,但这将使脚本仅支持 zsh。$*
IFS
zsh
$=*
$*
set -o SH_WORD_SPLIT
你应该使用"$@"
而不是$*
到处使用,除非你有一些非常特殊的理由不这样做:
compose() { docker-compose "$@"; }
run() { compose run --rm app "$@"; }
rails() { run rails "$@"; }