在Bash中输入heredoc的语法

时间:2016-06-26 21:26:13

标签: bash unix heredoc

我正在通过Ubuntu 16中的终端学习Unix bash。我正在编写一个简单的脚本,所以我可以练习为Unix编写代码。以下是代码示例:

report_uptime(){
cat << _EOF_
    <H2>System Uptime</H2>
    <PRE>$(uptime)</PRE>
    _EOF_
return
}

此代码不起作用,原因是因为在我之后我应该使用<<-而不是<<。有时<<有效。那么我应该何时使用<<,何时使用<<-

这有效:

report_uptime(){
cat <<- _EOF_
    <H2>System Uptime</H2>
    <PRE>$(uptime)</PRE>
    _EOF_
return
}

3 个答案:

答案 0 :(得分:5)

这不是猫的语法本身;它是shell支持的重定向运算符之一:

https://www.gnu.org/software/bash/manual/bashref.html#Here-Documents

  

3.6.6此处文件

     

这种类型的重定向指示shell从当前源读取输入,直到看到只包含 word (没有尾随空白)的行。然后,读取到该点的所有行都将用作命令的标准输入。

     

here-documents的格式为:

<<[-]word
        here-document
delimiter
     

不对字执行参数和变量扩展,命令替换,算术扩展或文件名扩展。如果引用 word 中的任何字符,则分隔符 word 上的引号删除结果,而here-document中的行不是扩大。如果 word 未加引号,则here-document的所有行都要进行参数扩展,命令替换和算术扩展,忽略字符序列\newline,并且必须使用'\'引用字符'\','$'和'`'。

     

如果重定向运算符为'&lt;&lt; - ',则所有前导制表符都将从输入行和包含分隔符的行中删除。这允许shell脚本中的文档以自然的方式缩进。

答案 1 :(得分:3)

严格来说,这不是cat实用程序的语法,而是shell本身的语法,即bash的语法。

您正在使用的构造称为“here-document”。 here-document将其内容提供给您在<<之前放置的任何命令的标准输入。

语法是:

command <<word
...
contents
...
END_TAG

word此处与END_TAG完全相同,或者可能是'END_TAG'-END_TAG-'END_TAG'

  • END_TAG如果没有单引号,则here-document的内容将进行替换。这意味着任何变量,或简单地说,“包含$的任何内容”都将被其值替换。

    $ tr 'a-z' 'A-Z' <<TR_END
    > This is my $HOME
    > TR_END
    THIS IS MY /USERS/KK
    

    >,一个大于号的符号和一个空格,就是所谓的辅助提示。我明白了,因为我直接在shell中输入了它,然后它在执行整个命令之前需要更多的输入行。它不是我输入的。)

  • 'END_TAG'使用单引号,here-document的内容将进行替换。这意味着,例如,如果您在here-document中编写$HOME,它将被添加到命令中,而不是/home/myname(或者您的主目录可能是什么)。< / p>

    $ tr 'a-z' 'A-Z' <<'TR_END'
    > This is my $HOME
    > TR_END
    THIS IS MY $HOME
    
  • 使用前导短划线(-,shell会在每行开头删除所有标签(但不是空格)这里的文档,包括最后的END_TAG行。

    $ tr 'a-z' 'A-Z' <<-TR_END
    >       This line has a tab.
    > This one does not.
    > TR_END
    THIS LINE HAS A TAB.
    THIS ONE DOES NOT.
    
  • 如果没有前导破折号,则外壳将剥离标签。 END_TAG需要是结束here-document的第一行(也是唯一的)。

    $ tr 'a-z' 'A-Z' <<TR_END
    >       This line has a tab.
    > This one does not.
    > TR_END
        THIS LINE HAS A TAB.
    THIS ONE DOES NOT.
    

bash shell也有一个名为“here-strings”的东西。它以类似的方式工作,但你只需要在命令中输入一行:

command <<<word

例如:

$ tr 'a-z' 'A-Z' <<<"hello world!"
HELLO WORLD!

答案 2 :(得分:2)

通常,结束标记不应缩进。将其移至第1列。同时删除return语句,它在bash中适用于我。