【问题标题】:How HereDocument worksHereDocument 的工作原理
【发布时间】:2019-01-24 12:26:24
【问题描述】:

有人可以解释一下下面的命令是如何工作的吗?忽略 sendmail 命令开关,我知道它是如何工作的。我想知道命令的其余部分是如何工作的,即 here-document(没有终止)、从标准输入读取的 cat 以及它如何通过管道传输到 sendmail。

SEND_MAIL()
{
`cat -  $body <<HERE | /usr/lib/sendmail -oi -t
From: $SENDER
To: $RECEIVER
Subject: $SUBJECT
Content-Type: text/html; charset=us-ascii
MIME-Version: 1.0`
}

更新:
为了回答一些困惑,上面的代码是由其他人编写的,令人惊讶的是它确实有效。代码的作者简单地执行了这个函数,它成功地向收件人发送了邮件,内容为$body。

【问题讨论】:

  • 它根本不应该工作,因为您缺少 here-doc 的结束分隔符。
  • 为什么整个命令块都是反引号?没有这些就行不通。添加 HERE 终结器,看看你是否可以不使用这些终结器,因为它们目前是让它尝试的黑客。
  • @chepner - 它确实有效,可能是因为 Jon 说的反引号。
  • 如果sendmail 产生任何输出,它将不起作用。

标签: bash shell sh sendmail heredoc


【解决方案1】:

这里的诀窍是-cat 是特殊的。它使cat 从标准输入中读取“文件”。这里的文档将文字行写入cat的标准输入,所以效果是将$body文件前面的文字行串联起来。

Bash 似乎接受了反引号中缺少的 here-document 分隔符,尽管它确实抱怨:

$ `cat <<HERE
echo foo
`
bash: warning: here-document at line 1 delimited by end-of-file (wanted `HERE')
foo
$

顺便说一句,那些反引号不是你想要的。试试

SEND_MAIL()
{
cat -  $body <<HERE | /usr/lib/sendmail -oi -t
From: $SENDER
To: $RECEIVER
Subject: $SUBJECT
Content-Type: text/html; charset=us-ascii
MIME-Version: 1.0
HERE
}

【讨论】:

  • 不过,缺少分隔符会导致其他错误;在给定的示例中,函数定义永远不会终止,因为关闭 } 仍然是此处文档的一部分。
  • @chepner 令人惊讶的是,反引号似乎限制了此处文档的范围。试试 foo () { `cat
  • 从技术上讲,终止此处文档的是输入的结尾;反引号只是分隔命令替换。
  • @chepner 我相信你在技术上是对的。但是在提示符下尝试 `cat
  • 感谢@Jon 的解释。但是该函数实际上发送带有 $body 内容的邮件,而不是您提到的“所以效果是连接文件 $body 前面的文字行”。 $body 变量的内容是一些 HTML。
猜你喜欢
  • 2021-03-20
  • 2011-10-26
  • 2017-12-02
  • 2014-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多