考虑以下脚本:
#!/bin/bash
foo=Hello
bar=Word
cat <<EOF
No quotes single word delimiter expands
$foo
$bar
EOF
cat <<'EOF'
Single-quoted single word delimiter does not expand.
$foo
$bar
EOF
cat <<"EOF"
Double-quoted single word delimiter does not expand.
$foo
$bar
EOF
cat <<EOF\ SOME\ MORE
Unquoted multi-word word delimiter does not expand.
Can we get it to expand?
$foo
$bar
EOF SOME MORE
在最后一种情况下,我使用了多字、不带引号的分隔符,但输出如下:
Unquoted multi-word word delimiter does not expand.
Can we get it to expand?
$foo
$bar
有没有办法让 bash 使用多字定界符时扩展变量?
当分隔符或其任何部分被引用(通过任何引用运算符,包括
'...'
,"..."
,\
,$'...'
,$"..."
)时,此处的文档不会进行任何扩展。分隔符是 shell 语法中的一个标记,因此任何字符(例如空格、制表符(以及在语言环境中归类为空白
;
的其他单字节字符)、 、 等<
)|
只能在引号中用作分隔符,因为它们在语言的语法中用于分隔标记,这意味着此处的文档中不会进行扩展,或者作为包含空格(例如$(foo bar)
、$[foo bar]
、$(( foo bar ))
、${--foo bar}
等)的 shell“标记”的一部分。或者您可以使用其他多字节空白字符,例如 UTF-8 编码的 U+00A0 NO-BREAK SPACE 或 U+2003 EM SPACE有趣的是,该空间似乎没有被视为引用:
使用多字节空白:
FOO
和上方是 U+2003字符BAR
,而不是 U+0020 ASCII 空格,以 UTF-8 编码为字节 0xe2 0x80 0x83。请注意,如果该脚本在这样的区域设置中运行:其中这三个字节中的任何一个是被归类为空白的字符的编码,那么该脚本将会失败,因为 bash 会将其视为空格或制表符之类的分隔符(这就是为什么通常建议在 bash 中引用非 ASCII 字符的原因之一)。
但实际上,据我所知,某些系统(比如某些 BSD)认为的唯一空白且具有单字节编码的非 ASCII 字符是 U+00A0,并且我只能找到将该字符编码为 0x80 的NeXT 字符集(至少根据 GNU libc),但我从未遇到过使用该字符映射的区域设置。
(您可能还会认为,在脚本中使用非 ASCII 空格肯定会让脚本的读者和维护者感到困惑)
Bash 手册中的Here Documents 部分:
并且引用包括“转义符、单引号和双引号”。所以看起来这是不可能的。上面没有提到的唯一扩展是历史和别名扩展,使用其中任何一个仍然需要对包含空格或其他元字符的单词进行引用。正如评论中所述,还有括号扩展和波浪线扩展,但在这里都没有帮助。