&lt; <eof和=“”<< eof =“”heredocs =“”in =“”shell =“”

时间:2015-07-28 14:32:57

标签: bash shell sh

=“”

我注意到它们之间存在一些区别:

<<EOF heredoc中,无法将新值分配给变量:

bash <<EOF
s=fds
echo $s
EOF

将打印空行,其中

bash <<\EOF
s=fds
echo $s
EOF

将打印变量s的值。

全局变量可以在<<EOF内访问,但不能在<<\EOF内访问(export可以访问<<\EOF内的变量):

s=fds
bash <<EOF
echo $s
EOF

将打印值fds,其中,

s=fds
bash <<\EOF
echo $s
EOF

将打印空行。

那么它们之间的区别是什么是合法的记录行为?

3 个答案:

答案 0 :(得分:8)

来自POSIX spec

  

如果引用 word 中的任何字符,则应通过在上执行引号删除来形成分隔符,并且不应展开here-document行。否则,分隔符应为单词本身。

因此<<EOF版本的shell会在运行此处的doc内容和<<\EOF(或<<'EOF'<<EO'F'之前展开所有变量等)版本不扩展内容(在这种情况下允许bash执行该操作)。

使用cat代替bash进行尝试,以便更清楚地了解正在发生的事情。

同时使用printf '[%s]\n' "$s"和/或可能bash -x代替bash

$ bash -x <<EOF
s=fds
printf '[%s]\n' "$s"
EOF
+ s=fds
+ printf '[%s]\n' ''
[]

$ bash -x <<\EOF
s=fds
printf '[%s]\n' "$s"
EOF
+ s=fds
+ printf '[%s]\n' fds
[fds]

答案 1 :(得分:1)

文档:http://www.gnu.org/software/bash/manual/bash.html#Here-Documents

在你的第一个例子中,分隔符是不加引号的,因此发生了变量扩展,就像你正在运行代码一样

echo "s=fds
echo $s" | bash

在当前shell中展开$s,它是空的。所以新shell看到了

s=fds
echo 

答案 2 :(得分:0)

阅读Advanced Bash Scripting Guide&amp; bash reference manual特别关于redirections

  

here-documents的格式为:

<<[-]word
        here-document
delimiter
  

无参数和变量扩展,命令替换,算术   对单词执行扩展或文件名扩展。如果有的话   引用的单词中的字符,分隔符是引用的结果   删除单词,并且不会展开here-document中的行。   如果单词不加引号,则here-文档的所有行都受到约束   参数扩展,命令替换和算术扩展,   字符序列\ newline被忽略,'\'必须用于   引用字符'\','$'和'`'。