发送多个csv附件,简单的Bash错误?

问题描述 投票:1回答:1

我是Bash脚本的新手,我正在尝试修改一些我从网上获取的代码。基本上我正在尝试将多个文件附加到同一封电子邮件中。

    #!/bin/bash

    function get_mimetype(){
    file --mime-type "$1" | sed 's/.*: //'
    }
    declare -a attachments
    attachments=("A_PTDIFF.CVS" "A_PTMISS.CVS" "A_PTNPOS.CVS" "A_PTRCON.CVS" 
    )

    # Build headers
    {

     printf '%s\n'"From: jrpng
     To: [email protected]
     Subject: Test new Bash script
     Mime-Version: 1.0
     Content-Type: multipart/mixed; boundary=\"=== Boundary ===\"
     --${=== Boundary ===}
     Content-Type: text/plain; charset=\"US-ASCII\"
     Content-Transfer-Encoding: 7bit
     Content-Disposition: inline
     The reports are attached to this email as requested
     "
     for file in "${attachments[@]}"; do
     [ ! -f "$file" ] && echo "Attachment $file not found, omitting file" 
     >&2 && continue
     mimetype=$(get_mimetype "$file")
     printf '%s\n' "--${=== Boundary ===}
     Content-Type: $mimetype
     Content-Transfer-Encoding: base64
     Content-Disposition: attachment; filename=\"$file\"
     "
     base64 "$file"
     echo
     done
     # print last boundary with closing --
     printf '%s\n' "--${=== Boundary ===}--"
     } | /usr/lib/sendmail -t -oi

好的,当通过bash sendmail54.sh运行时,我得到以下内容

    sendmail54.sh: line 22: From: jrpng
    To: [email protected]
    Subject: Test new Bash script
    `Mime-Version: 1.0
    Content-Type: multipart/mixed; boundary="=== Boundary ==="
    --${=== Boundary ===}
    Content-Type: text/plain; charset="US-ASCII"
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline
    The reports are attached to this email as requested
    : bad substitution
    No recipient addresses found in header

不知道错误信息告诉我什么?

如果有一个更好的方法来实现我想要实现的目标,我非常乐意尝试这一点,正如bash脚本编写所说的那样,所以我在黑暗中试图让这个工作起作用。

linux bash shell
1个回答
1
投票

您有许多基本的语法错误和误解。

显然原始代码有一个变量boundary="randomstring",然后用--${boundary}插入到正确的位置。但是你试图在${...}中使用边界字符串本身,这只是无意义 - 括号之间的内容是变量的名称。

此外,您的邮件消息需要一些空行才能生效。一般结构是

From: whoever
To: wherever
Subject: whatever
Mime-version: 1.0
Content-type: multipart something something; boundary="randomstring"

<- empty line between message headers and first body part

--randomstring
Content-type: of first attachment
x-headers: and etc

<- empty line before here; now the actual attachment data

--randomstring
Content-type: of second attachment
x-headers: and etc

payload of second attachment goes here, again after an empty line

--randomstring--

手动拼凑电子邮件消息要求您了解大多数人根本不想要的MIME。如果您安装了mutt等合理的邮件程序,则无需了解如何正确格式化SMTP MIME邮件的详细信息。

无论如何,这是尝试修复您当前的代码,注释和适当的缩进。

function get_mimetype(){
  file --mime-type "$1" | sed 's/.*: //'
}
declare -a attachments
attachments=("A_PTDIFF.CVS" "A_PTMISS.CVS" "A_PTNPOS.CVS" "A_PTRCON.CVS")

{
  boundary="--random$$string--"
  # You were missing a space after '%s\n'
  # Also, I'm breaking this into multiple arguments for legibility
  printf '%s\n' \
          "From: jrpng" \
          "To: [email protected]" \
          "Subject: Test new Bash script" \
          "Mime-Version: 1.0" \
          "Content-Type: multipart/mixed; boundary=\"$boundary\"" \
          "X-Comment: # notice the empty line after this one" \
          "" \
          "--${boundary}" \
          "Content-Type: text/plain; charset=\"US-ASCII\"" \
          "Content-Transfer-Encoding: 7bit" \
          "Content-Disposition: inline" \
          "X-Comment: # these headers are all superfluous really" \
          "X-Comment: # (default is text/plain us-ascii 7bit inline)" \
          "X-Comment: # but the next empty line is important" \
          "" \
          "The reports are attached to this email as requested" \
          ""

  for file in "${attachments[@]}"; do
      [ ! -f "$file" ] &&
          echo "Attachment $file not found, omitting file"  >&2 && 
          continue
      mimetype=$(get_mimetype "$file")
      printf '%s\n' \
          "--${boundary}" \
          "Content-Type: $mimetype" \
          "Content-Transfer-Encoding: base64" \
          "Content-Disposition: attachment; filename=\"$file\"" \
          ""
      base64 "$file"
      echo
  done
  printf '%s\n' "--${boundary}--"
} | /usr/lib/sendmail -t -oi
© www.soinside.com 2019 - 2024. All rights reserved.