alias -g '${1+"$@"}'='"$@"',它有什么作用?

2 shell zsh alias

大多数makefile 都有这组奇怪的符号'${1+"$@"}'。$@ 是 makefile 目标文件名。但是,为什么人们会尝试使用复杂的符号,例如'${1+"$@"}'

cuo*_*glm 8

目的是${1+"$@"}为了便携。

如果没有位置参数,POSIX 定义的 $@将扩展为空。但是原始的 Bourne shell(/bin/sh在 Solaris 10 及之前)会将其扩展为空字符串""。Using${1+"$@"}是一种解决方法,因为"$@"只有$1在设置时才展开。

不幸的是,这个结构在 zsh 3.x 和 pre 4.3 中不起作用,因为 zsh在 sh 仿真模式下执行分词${1+"$@"}(设置了shwordsplit):

$ set -- '1 2'
$ for i in ${1+"$@"}; do echo $i; done
1
2
Run Code Online (Sandbox Code Playgroud)

"$@" 处理得当:

$ set -- '1 2'
$ for i in "$@"; do echo $i; done
1 2
Run Code Online (Sandbox Code Playgroud)

因此alias -g '${1+"$@"}'='"$@"',请确保在使用${1+"$@"}. 这允许${1+"$@"}在 zsh 中使用该构造,因为它将被替换为"$@"before 扩展(您必须完全使用 string ${1+"$@"},没有前导或尾随单词字符)。


您可以做的另一项工作是,"$@"如果没有位置参数,则完全忽略 using ,通过检查$#

case $# in
  (0) func ;;
  (*) func "$@" ;;
esac
Run Code Online (Sandbox Code Playgroud)

它需要更多的工作,但完全便携。