I've noticed something weird:
Y=""
echo ${Y:-"\n"}
echo "${Y:-"\n"}"
prints
\n
n
Why is the second line n
, not \n
? Is this a bug?
It looks as if Bash parsed this as a concatenation of two quoted strings with an unquoted string in between ("${Y:-"
and \n
and "}"
) but this doesn't seem to be the case since the commands
echo $(echo "\n")
echo "$(echo "\n")"
echo "${Y:-"'\n'"}"
output
\n
\n
'n'
I'm using GNU bash, version 4.3.11.
答案 0 :(得分:3)
我怀疑在处理:-
之后的单词时存在一个错误(事实上,我似乎记得读过一些关于此的内容,但我记不起来了。)
如果没有引用该值,我会得到我期望的结果......
$ echo ${Y:-\n}
n
$ echo "${Y:-\n}"
\n
这也是您在dash
中得到的结果(忽略dash
实际生成文字换行的事实,因为POSIX要求echo
处理转义字符,bash
只有在使用非标准-e
选项时才会这样做。)
在此示例中,引用默认值会保留反斜杠。由于参数扩展产生反斜杠,引用删除不将其删除。
$ echo ${Y:-"\n"} # Equivalent to echo "\n", so the output makes sense
\n
似乎没有任何理由让bash
在最后一个例子中表现不同只是因为引用了整个参数扩展。这几乎就像引用删除被应用两次,一次删除外部双引号并再次错误地删除反斜杠。
# Quote removal discards the backslash: OK
$ echo \n
n
# Quote removal discards the double quotes: OK
$ echo "n"
n
# Quote removal discards the first backslash after `\\` is recognized
# as a quoted backslash: OK
$ echo \\n
\n
# Quote removal discards the double quotes, but leaves
# backslash: OK
$ echo "\n"
\n
# Is quote removal discarding both the double quotes *and* the backslash? Not OK
$ echo "${Y:-"\n"}"
n
相关,zsh
(bsd_echo
)选项设置输出\n
,而不是n
。
% Y=""
% echo "${Y:-"\n"}"
\n
答案 1 :(得分:2)
这里概述了类似POSIX的主要shell如何处理以下命令:
Y=""
printf '%s\n' ${Y:-"\n"} ${Y:-'\n'} "${Y:-"\n"}" "${Y:-'\n'}"
请注意,我已使用单个引号添加了变体。
dash [v0.5.8]
\n
\n
\n
'\n'
zsh [v5.0.8]
\n
\n
\n
'\n'
bash [v4.3.42]
\n
\n
n
'\n'
ksh [93u+]
\n
\n
n
'\n'
奇怪的是,在所有 shell中,'\n'
中的"..."
会保留单引号,同时在中删除它们未加引号的案例。
对于"\n"
,bash
和ksh
都表现出OP发现的奇怪现象,而dash
和zsh
则没有。
答案 2 :(得分:0)
也许我看错了,但我没有看到任务中的任何不一致,默认值为Y
,引用或未加引号。每种情况下的echo
表达式归结为:
$ echo "\n"
\n
$ echo ""\n""
n
在第一种情况下,你有引用的字符串"\n"
,在第二种情况下,你有一个\n
(只是n
)