Herestrings 中的 ANSI C 引用如何工作?

发布于 2025-01-09 22:51:04 字数 739 浏览 1 评论 0原文

为什么这不起作用?

bla="
multi

line

string
"
cat -A <<EOF
${bla//\$'\n'/\\\$'\n'}
EOF

这有效:

cat -A <<EOF
$(cat <<<${bla//$'\n'/\\$'\n'})
EOF

正如评论中所述,这也有效:

newline=$'\n'
cat -A <<EOF
${bla//$newline/\\$newline}
EOF

预期:

\$
multi\$
\$
line\$
\$
string\$

我想这与引用以及heredocs的工作方式有关。 但由于 set -x 不适用于参数扩展调试,我无法弄清楚。

GNU Bash 参考手册 中解释它的链接也会有所帮助。

注意: 预期: 中的 $ 来自 cat -A 选项,代表换行符 \ n 字符。

Why is this not working?

bla="
multi

line

string
"
cat -A <<EOF
${bla//\

this works:

cat -A <<EOF
$(cat <<<${bla//

as noted in a comment this also works:

newline=

Expected:

\$
multi\$
\$
line\$
\$
string\$

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\\

this works:


as noted in a comment this also works:


Expected:


I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'} EOF

this works:


as noted in a comment this also works:


Expected:


I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\

as noted in a comment this also works:


Expected:


I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\\

this works:


as noted in a comment this also works:


Expected:


I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'} EOF

this works:


as noted in a comment this also works:


Expected:


I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'}) EOF

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\\

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'} EOF

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n' cat -A <<EOF ${bla//$newline/\\$newline} EOF

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\\

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'} EOF

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\\

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'} EOF

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'}) EOF

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'/\\\

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

\n'} EOF

this works:

as noted in a comment this also works:

Expected:

I guess it has something to do with Quoting and how heredocs work.
But as set -x is not working for parameter expansion debugging, i could not figue it out.

A link to where it is explained in the GNU Bash Reference Manual would also help.

Note: The $ in Expected: are from cat -A option and stand for the newline \n character.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扛起拖把扫天下 2025-01-16 22:51:04

我认为你需要删除参数扩展中的一些 \

也就是说,它应该是 ${bla//$'\n'\$$'\n'}

$ bla="
multi
line
string
"
$ printf "%q\n" "$bla"

我在每行末尾添加了一个 $

$ bla="
multi
line
string
"
$ printf "%q" "$bla"

我正在使用

$ echo $BASH_VERSION
5.1.16(1)-release
\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

我在每行末尾添加了一个 $


我正在使用



\n'/\$'\n'}
EOF
$
multi$
line$
string$
$

我在每行末尾添加了一个 $


我正在使用



\nmulti\nline\nstring\n'
$ printf "%s" "${bla//

我正在使用



\nmulti\nline\nstring\n'
$ gcat -A <<EOF
${bla//

我在每行末尾添加了一个 $


我正在使用



\n'/\$'\n'}
EOF
$
multi$
line$
string$
$

我在每行末尾添加了一个 $

我正在使用

\n'/\$'\n'}" $ multi$ line$ string$ $ printf "%q" "${bla//

我正在使用

\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

我在每行末尾添加了一个 $

我正在使用

\n'/\$'\n'} EOF $ multi$ line$ string$ $

我在每行末尾添加了一个 $

我正在使用

\n'/\$'\n'}"

我正在使用

\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

我在每行末尾添加了一个 $

我正在使用

\n'/\$'\n'} EOF $ multi$ line$ string$ $

我在每行末尾添加了一个 $

我正在使用

$\nmulti$\nline$\nstring$\n'

我正在使用

\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

我在每行末尾添加了一个 $

我正在使用

\n'/\$'\n'} EOF $ multi$ line$ string$ $

我在每行末尾添加了一个 $

我正在使用

I think you need to remove some of the \ in the parameter expansion.

That is, it should read ${bla//$'\n'\$$'\n'}.

$ bla="
multi
line
string
"
$ printf "%q\n" "$bla"

What I have adds a $ at the end of each line.

$ bla="
multi
line
string
"
$ printf "%q" "$bla"

I am using

$ echo $BASH_VERSION
5.1.16(1)-release
\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

What I have adds a $ at the end of each line.


I am using



\n'/\$'\n'}
EOF
$
multi$
line$
string$
$

What I have adds a $ at the end of each line.


I am using



\nmulti\nline\nstring\n'
$ printf "%s" "${bla//

I am using



\nmulti\nline\nstring\n'
$ gcat -A <<EOF
${bla//

What I have adds a $ at the end of each line.


I am using



\n'/\$'\n'}
EOF
$
multi$
line$
string$
$

What I have adds a $ at the end of each line.

I am using

\n'/\$'\n'}" $ multi$ line$ string$ $ printf "%q" "${bla//

I am using

\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

What I have adds a $ at the end of each line.

I am using

\n'/\$'\n'} EOF $ multi$ line$ string$ $

What I have adds a $ at the end of each line.

I am using

\n'/\$'\n'}"

I am using

\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

What I have adds a $ at the end of each line.

I am using

\n'/\$'\n'} EOF $ multi$ line$ string$ $

What I have adds a $ at the end of each line.

I am using

$\nmulti$\nline$\nstring$\n'

I am using

\nmulti\nline\nstring\n' $ gcat -A <<EOF ${bla//

What I have adds a $ at the end of each line.

I am using

\n'/\$'\n'} EOF $ multi$ line$ string$ $

What I have adds a $ at the end of each line.

I am using

裂开嘴轻声笑有多痛 2025-01-16 22:51:04

为什么这不起作用?

显然是因为 Bash 在 ANSI-C 引用方面长期存在行为不一致。

其 ANSI-C 引用文档 不会任何上下文异常。

其heredocs文档没有做出任何特殊规定这似乎相关:

如果 [分隔符] 未加引号,则此处文档的所有行都将受到
参数扩展、命令替换和算术扩展,
字符序列 \newline 被忽略,并且必须使用 '\'
引用字符“\”、“$”和“`”。

由于我认为最后一句话有一个隐含的“为了消除它们的特殊意义”,所以我在参数扩展的描述中没有看到任何东西表明参数扩展在定界文档中的工作方式与在其他地方的工作方式不同。

但显然,确实如此。具体来说,ANSI-C 带引号的字符串在此处文档之外的参数扩展中被识别,但在词汇上相同的此处文档内的参数扩展中则不能被识别。这似乎会影响所有形式的参数扩展,这些参数扩展涉及参数名称以外的文本作为扩展的一部分,并且它不依赖于任何 C 样式转义序列的使用。示例:

$ ex1=abcdef
$ cat <<<${ex1#*
ex2=a\$bcdef
$ cat <<<${ex2%

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

var=

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:


我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:


我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'*} a$ $ cat <<EOF ${ex2%

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:


我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:


我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:


我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'*} ${ex2/

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:


我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:


我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'/X} EOF a aXcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b' $ cat <<EOF ${ex1/${var}/X} EOF aXcdef

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'*} a$ $ cat <<EOF ${ex2%

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'*} ${ex2/

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'/X} EOF a aXcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} cdef $ cat <<EOF ${ex1#*

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

b'} EOF abcdef

实际行为似乎是引入 C 样式引号的 $ 被视为文字字符,但单引号根据其作为引号字符的普通角色进行解释。最简单的解决方法似乎是将 ANSI-C 引用的文本分配给一个变量:

我首先倾向于猜测这种行为差异与 ANSI-C 引用在定界文档正文中未被直接识别有关。然而,在heredocs中都不能直接识别单引号或双引号的引用,但这些引用形式仍然可以在嵌入heredocs的参数扩展内识别。我很难理解为什么不应将某些参数扩展在此处的解释与在外部的解释不同视为错误。

Why is this not working?

Apparently because Bash has longstanding behavioral inconsistencies around ANSI-C quoting.

Its documentation for ANSI-C quoting does not make any contextual exceptions.

Its documentation for heredocs does not make any special provision that seems relevant:

If [the delimiter word] is unquoted, all lines of the here-document are subjected to
parameter expansion, command substitution, and arithmetic expansion,
the character sequence \newline is ignored, and ‘\’ must be used to
quote the characters ‘\’, ‘$’, and ‘`’.

Inasmuch as I take that last sentence to have an implied "in order to remove their special significance", I see nothing there or in the description of parameter expansion to suggest that parameter expansion works differently in a heredoc than it works elsewhere.

But demonstrably, it does. Specifically, ANSI-C quoted strings are recognized in parameter expansions outside of heredocs, but not in lexically the same parameter expansions inside heredocs. This seems to affect all forms of parameter expansion that involve text other than the parameter name as part of the expansion, and it does not depend on the use of any of the C-style escape sequences. Examples:

$ ex1=abcdef
$ cat <<<${ex1#*
ex2=a\$bcdef
$ cat <<<${ex2%

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

var=

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:


I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:


I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'*} a$ $ cat <<EOF ${ex2%

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:


I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:


I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:


I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'*} ${ex2/

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:


I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:


I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'/X} EOF a aXcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b' $ cat <<EOF ${ex1/${var}/X} EOF aXcdef

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'*} a$ $ cat <<EOF ${ex2%

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'*} ${ex2/

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'/X} EOF a aXcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} cdef $ cat <<EOF ${ex1#*

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

b'} EOF abcdef

The actual behavior seems to be that the $ introducing the C-style quote is taken as a literal character, but the single quotes are interpreted according to their ordinary role as quote characters. The simplest workaround seems to be to assign the ANSI-C-quoted text to a variable:

I was first inclined to guess that this behavioral difference is related to ANSI-C quoting not being recognized directly in the body of a heredoc. However, neither is quoting with single- or double-quotes recognized directly in heredocs, yet those quoting forms are still recognized inside parameter expansions embedded in heredocs. I'm having a hard time seeing why it should not be considered a bug that some parameter expansions are interpreted differently inside heredocs than they are outside.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文