Bash - 具有可变扩展的heredoc,保留换行符

时间:2017-11-17 15:31:09

标签: bash

我正在尝试在bash脚本中生成发送邮件客户端ssmtp的邮件文本(而不是将其放在文件中)。

使用heredoc我想出了这个:

MAILTO=me@mydomain.com
FROM=admin@mydomain.com
SUBJ="$HOSTNAME: Daemon not running"

read -d '' msg <<EOF
    To: $MAILTO
    From: $FROM
    Subject: $SUBJ

    Please check $HOSTNAME.
    Daemon has stopped running.

    -Admin
EOF

echo $msg | ssmtp $MAILTO

(这不起作用。ssmtp不发送邮件,因为文本不保留换行符。)

如果我echo $msg,那么我看到heredoc中的换行不会被保留。我怎么能做到这一点?

另外:这个

的区别在哪里
{
  echo "To: $MAILTO"
  echo "From: $FROM"
  echo "Subject: $SUBJ"
  echo
  echo "Please check $HOSTNAME"
} | ssmtp $MAILTO

和第一个例子?是否已执行所有echo个命令并将结果传送到ssmtp?这不是我的第一个例子吗?我不能echo将文本和管道echo输出到命令吗?

2 个答案:

答案 0 :(得分:2)

首先,您不需要read

msg="\
To: $MAILTO
From: $FROM
Subject: $SUBJ

Please check $HOSTNAME.
Daemon has stopped running.

-Admin"

其次,你应该总是引用参数扩展;你知道什么时候这样做不是你想要的,这种情况很少见。

echo "$msg" | ssmtp "$MAILTO"

最后,考虑一下您是否需要 msg

ssmtp "$MAILTO" <<EOF
To: $MAILTO
From: $FROM
Subject: $SUBJ

Please check $HOSTNAME.
Daemon has stopped running.

-Admin
EOF

答案 1 :(得分:1)

您的第二个示例使用Command Grouping。因此,您的假设是,所有echo命令都已执行并通过管道传送到ssmtp是正确的。

从手册:

  

在大括号之间放置命令列表会导致列表在当前shell上下文中执行。没有创建子shell。

关于你的第一个例子。这不是heredoc的错。尝试将msg括在引号中:

echo "$msg" | ssmtp "$MAILTO"