【问题标题】:Input syntax for heredoc in BashBash 中 heredoc 的输入语法
【发布时间】:2016-10-28 20:11:02
【问题描述】:

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

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

此代码不起作用,原因是在 cat 之后我应该使用 &lt;&lt;- 而不是 &lt;&lt;。有时&lt;&lt; 有效。那么我应该什么时候使用&lt;&lt;,什么时候应该使用&lt;&lt;-

这行得通:

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

【问题讨论】:

  • 你能添加一个可行的案例吗?
  • 你确定你可以在&lt;&lt;_EOF_之间有空格吗?
  • 您还可以提及这是什么语言或外壳。重击?短跑?克什?
  • 好的,这是一个功能,我让它工作了。唯一的问题是&lt;&lt; 应该是&lt;&lt;-。问题不是为什么这不起作用,而是何时使用&lt;&lt; 以及何时使用&lt;&lt;-?我正在使用 bash

标签: bash unix heredoc


【解决方案1】:

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

【讨论】:

  • 底部的代码有效。我的问题不是“为什么我的代码不起作用?”。问题是,我什么时候使用&lt;&lt;,什么时候使用&lt;&lt;-,因为在这个功能的原因中&lt;&lt; 将不起作用但&lt;&lt;- 会。
【解决方案2】:

这本身不是 cat 语法;它是您的 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 中的任何字符被引用,则 delimiter 是在 word 上去除引号的结果,并且 here-document 中的行不是扩大。如果word不加引号,则here-document的所有行都经过参数扩展、命令替换和算术扩展,字符序列\newline被忽略,必须使用'\'来引用字符“\”、“$”和“`”。

如果重定向操作符是“delimiter 的行中删除。这允许 shell 脚本中的 here-documents 以自然的方式缩进。

【讨论】:

  • 并确保您注意最后一行。 “制表符”。实际上,这只会去除制表符,而不是空格。
  • 这是有道理的。当我没有 [-] 时,它将脚本的其余部分视为字符串。
【解决方案3】:

这并不是严格意义上的cat 实用程序的语法,而是shell 本身的语法,即bash

您正在使用的构造称为“此处文档”。此处文档将其内容输入到您在&lt;&lt; 之前输入的whatever 命令的标准输入中。

语法是这样的:

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
    

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

  • 'END_TAG'使用单引号,此处文档的内容将进行替换。这意味着,例如,如果您在 here-document 中写入 $HOME,它将像这样被输入命令,而不是像 /home/myname(或任何您的主目录)。

    $ tr 'a-z' 'A-Z' <<'TR_END'
    > This is my $HOME
    > TR_END
    THIS IS MY $HOME
    
  • 使用前导破折号 (-),shell 将去掉 here-document 每一行开头的所有制表符(但不包括空格) ,包括末尾带有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.
    
  • 没有前导破折号,shell将不会剥离标签。 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!

【讨论】:

    猜你喜欢
    • 2013-04-16
    • 2020-01-01
    • 2012-01-28
    • 2011-04-17
    • 2021-09-08
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    相关资源
    最近更新 更多