Sib*_*ing 2 shell bash quoting
我知道单引号不会评估里面的内容,而双引号会。我经常看到人们引用美元符号的评价。这里有些例子:
for i in "${indices[@]}"; doif [ "${a}" == 0 ]; thenffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4如果我们不双引号美元符号表达式怎么办?AFAIK,for循环仍然有效。
你的三个例子并不完全一样。
在最后两个:
if [ "${a}" == 0 ]; then
ffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4
Run Code Online (Sandbox Code Playgroud)
如果$a没有被引用,并且它的值包含字符$IFS(默认为空格、制表符和换行符)或通配符,这将导致[接收三个以上的参数(除了[和]),从而导致错误;同样,如果 的值为$a空字符串,这将导致
[接收的参数太少:
$ (a=0; [ $a == 0 ] && echo OK)
OK
Run Code Online (Sandbox Code Playgroud)
(但前提是$IFS当前碰巧不包含0)
$ (a='foo bar'; [ $a == 0 ] && echo OK)
bash: [: too many arguments
Run Code Online (Sandbox Code Playgroud)
(默认值为$IFS)
$ (a=; [ $a == 0 ] && echo OK)
bash: [: ==: unary operator expected
Run Code Online (Sandbox Code Playgroud)
(即使是空的$IFS或 with zsh(否则不会在未加引号的扩展中实现隐式 split+glob 运算符))
$ (a='*'; [ $a == 0 ] && echo OK)
bash: [: too many arguments
Run Code Online (Sandbox Code Playgroud)
(在包含至少 2 个非隐藏文件的目录中运行时)。
引用,没有错误:
$ (a='foo bar'; [ "$a" == 0 ] && echo OK)
$ (a=; [ "$a" == 0 ] && echo OK)
Run Code Online (Sandbox Code Playgroud)
你的第一个例子是不同的。当涉及到数组时,关于双引号内扩展的规则是特殊的;如果a表示一个数组,则:
$a是数组的第一个元素(严格地说,${a[0]}即使未定义索引0 处的元素也是如此);
${a[*]}或者${a[@]}是数组的元素,另外在$IFS(空格、制表符、换行符默认)处分割;
"${a[@]}"是数组的元素,而不是在 处拆分$IFS。
因此,您的循环for i in "${indices[@]}"; do ...实际上并不相同,具体取决于数组的内容。例如:
$ (declare -a a=(a b c); printf '%s\n' $a)
a
$ (declare -a a=(a b c); printf '%s\n' ${a[*]})
a
b
c
$ (declare -a a=(a 'b c'); printf '%s\n' ${a[*]})
a
b
c
$ (declare -a a=(a 'b c'); printf '%s\n' ${a[@]})
a
b
c
$ (declare -a a=(a 'b c'); printf '%s\n' "${a[*]}")
a b c
$ (declare -a a=(a 'b c'); printf '%s\n' "${a[@]}")
a
b c
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3098 次 |
| 最近记录: |