我想要有标准参数,即我的最小可重复示例是:
#!/usr/bin/zsh
a=${1:a}
printf 'a: "%s"\n' "${a}"
b=${2:./build}
printf 'b: "%s"\n' "${b}"
我希望看到,当./demo.zsh
不带参数运行时:
a: "a"
b: "./build"
相反我得到了
a: ""
./demo.zsh:4: bad floating point constant
- 为什么
${1:a}
似乎假设$1
设置并且非零,但$a
展开后的却是空字符串? - 浮点错误解析从何而来?如果我
./build
用替换build
,它会抱怨它b
是一个未知的修饰符。
如果我跑./demo.zsh asdf bar
,我会得到
a: "/tmp/fasf"
./demo.zsh:4: bad floating point constant
坦率地说,这更令人困惑;它/tmp/
来自哪里(它是 cwd)。
${1:a}
此语法对于提供默认值而言是不正确的。它尝试使用 a 作为修饰符,而这并不是您想要的。错误消息
bad floating point constant
和unknown modifier
是由于 zsh 尝试将a
和解释./build
为修饰符或特殊语法,但事实并非如此。我使用 重现了该脚本
Bash
,它实际上应该以相同的方式在 中工作Zsh
。输出 1:
输出 2:
该语法
${1:a}
不是为位置参数提供默认值的正确方法。${1:-default}
如果参数未设置或为空,则应使用提供默认值。${1:-a}
这意味着如果$1
未设置或为空,则使用 a 作为默认值。${2:-./build}
这意味着如果$2
未设置或为空,则用作./build
默认值。这是基于Stéphane 的评论。
在 Zsh shell 中,与应用修饰符的
${1:a}
相同。修饰符的文档如下:$1:a
$1
:a
:a
zshexpn(1)
因此,
${1:a}
如果 为空或未设置,则为空字符串。如果为某个非空字符串并且当前目录为 ,$1
则它将是一个以 开头的路径名。/tmp/fasf
$1
/tmp/fasf
:.
不是与:a
is 相同意义上的有效修饰符,但扩展${1:n}
对整数有效n
,并将返回 中字符串的尾部$1
,从偏移量 开始n
。这是从 shell 继承的ksh93
。这意味着由于.
不是有效修饰符,shell 会尝试将其解释为算术表达式,以便计算子字符串。这就是为什么您会得到 错误的原因${2:./build}
,因为字符串./build
不能用作偏移量。最后,您想要使用的是在未设置或为空的情况下提供默认值的标准
${1-a}
或扩展之一。${1:-a}
$1