Bash中Heredoc的输入语法

Joh*_*ohn 4 unix bash heredoc

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

report_uptime(){
cat << _EOF_
    <H2>System Uptime</H2>
    <PRE>$(uptime)</PRE>
    _EOF_
return
}
Run Code Online (Sandbox Code Playgroud)

这段代码不起作用,原因是因为在cat之后,我应该使用<<-而不是<<。有时<<有效。那么,我什么<<时候应该使用<<-?什么时候应该使用?

这有效:

report_uptime(){
cat <<- _EOF_
    <H2>System Uptime</H2>
    <PRE>$(uptime)</PRE>
    _EOF_
return
}
Run Code Online (Sandbox Code Playgroud)

mel*_*ene 5

这本身不是cat语法;它是您的Shell支持的重定向操作符之一:

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

3.6.6此处文件

这种重定向指示外壳程序从当前源读取输入,直到看到仅包含单词(无尾随空格)的行。直至该点为止的所有行都将用作命令的标准输入。

此处文档的格式为:

<<[-]word
        here-document
delimiter
Run Code Online (Sandbox Code Playgroud)

对单词不执行参数和变量扩展,命令替换,算术扩展或文件名扩展。如果对word中的任何字符加引号,则定界符是对word删除引号的结果,并且本文档中的行不会扩展。如果未引用word,则对本文的所有行进行参数扩展,命令替换和算术扩展,将\newline忽略字符序列,并且必须使用'\'来引用字符'\','$',和'`'。

如果重定向运算符为'<<-',则所有前导制表符将从输入行和包含delimiter的行中删除。这允许外壳脚本中的此处文档以自然方式缩进。


Kus*_*nda 5

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

您使用的构造称为“此处文档”。此处文档将其内容输入到您之前输入的任何<<命令的标准输入中。

语法是这样的:

command <<word
...
contents
...
END_TAG
Run Code Online (Sandbox Code Playgroud)

这里word的 要么与 完全相同END_TAG,要么可能是'END_TAG',-END_TAG-'END_TAG'

  • END_TAG如果没有单引号,则此处文档的内容将被替换。这意味着任何变量,或者简单地说,“任何包含$”的内容都将被替换为它的值。

    $ tr 'a-z' 'A-Z' <<TR_END
    > This is my $HOME
    > TR_END
    THIS IS MY /USERS/KK
    
    Run Code Online (Sandbox Code Playgroud)

    >大于号和空格,就是所谓的辅助提示符。我明白这一点是因为我直接在 shell 中键入它,并且它需要更多的输入行才能执行整个命令。它是不是我打字的。)

  • 'END_TAG'使用单引号时,此处文档的内容不会替换。这意味着,例如,如果您$HOME在此处文档中写入,它将像那样输入到命令中,而不是像/home/myname(或您的主目录可能是什么)那样。

    $ tr 'a-z' 'A-Z' <<'TR_END'
    > This is my $HOME
    > TR_END
    THIS IS MY $HOME
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用前导破折号 ( -),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.
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果没有前导破折号,外壳将不会剥离选项卡。需要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.
    
    Run Code Online (Sandbox Code Playgroud)

shellbash还有一个叫做“here-strings”的东西。它的工作方式类似,但您只需向命令中输入一行:

command <<<word
Run Code Online (Sandbox Code Playgroud)

例如:

$ tr 'a-z' 'A-Z' <<<"hello world!"
HELLO WORLD!
Run Code Online (Sandbox Code Playgroud)