我目前正在通过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)
这本身不是cat语法;它是您的Shell支持的重定向操作符之一:
https://www.gnu.org/software/bash/manual/bashref.html#Here-Documents
3.6.6此处文件
这种重定向指示外壳程序从当前源读取输入,直到看到仅包含单词(无尾随空格)的行。直至该点为止的所有行都将用作命令的标准输入。
此处文档的格式为:
Run Code Online (Sandbox Code Playgroud)<<[-]word here-document delimiter对单词不执行参数和变量扩展,命令替换,算术扩展或文件名扩展。如果对word中的任何字符加引号,则定界符是对word删除引号的结果,并且本文档中的行不会扩展。如果未引用word,则对本文的所有行进行参数扩展,命令替换和算术扩展,将
\newline忽略字符序列,并且必须使用'\'来引用字符'\','$',和'`'。如果重定向运算符为'<<-',则所有前导制表符将从输入行和包含delimiter的行中删除。这允许外壳脚本中的此处文档以自然方式缩进。
严格来说,这并不是关于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)