bash - 如果从 bash 脚本执行,则乱码邮件命令
问题描述
如果命令失败,我正在编写一个简单的 Bash 脚本来执行备份并在最后发送带有修改主题的邮件。
这是脚本的一个片段:
BACKUP_CMD="ls -1" # Just an example command
MAIL_RECIPIENTS="me@domain" # Recipient addresses (space separated list)
MAIL_SUBJECT="Backup script" # Mail subject
MAIL_FAIL_SUBJECT_PREPEND="[!!! ---FAILURE--- !!!] "
MAIL_CMD="mail -a \"Content-Type: text/plain; charset=UTF-8\" -s \"SUBJECT\" RECIPIENTS" # Mail send command
# Execute backup
output="$($BACKUP_CMD)"
status=$?
# Check exit status code and compose the mail message
echo $status
if [ "$status" -eq "0" ]; then
mail_subject=$MAIL_SUBJECT
mail_text="${output}"
else
mail_subject="$MAIL_FAIL_SUBJECT_PREPEND $MAIL_SUBJECT"
mail_text="$output\n\nExit status code: $status"
fi
# Compose the mail command with subject and recipients list
mail_cmd=$MAIL_CMD
mail_cmd="${mail_cmd/SUBJECT/$mail_subject}"
mail_cmd="${mail_cmd/RECIPIENTS/$MAIL_RECIPIENTS}"
echo "$mail_text" | ${mail_cmd}
邮件未发送,脚本退出并出现以下错误send-mail
:
send-mail: RCPT TO:<Backup", charset=UTF-8"@server.domain> (501 5.1.3 Bad recipient address syntax)
Can't send mail: sendmail process failed with error code 1
似乎 bash 在邮件命令的末尾“打乱”了参数。
我无法理解的是,如果我打印 $mail_cmd 它似乎是正确的:
mail -a "Content-Type: text/plain; charset=UTF-8" -s "Backup script" me@domain
我哪里错了?
解决方案
我相信你的脚本可以用一些 bash 数组来修复:
backup_cmd=(ls -1)
mail_cmd2=(mail -a "Content-Type: text/plain; charset=UTF-8" -s)
...
output=$("${backup_cmd[@]}")
...
mail_cmd=("${mail_cmd2[@]}")
mail_cmd+=("$mail_subject")
mail_cmd+=( $MAIL_RECIPIENTS )
# MAIL_RECIPIENTS should be changed to a bash array too!
echo "$mail_text" | "${mail_cmd[@]}"
但是重构脚本并创建一个函数会更好:
mail_cmd() {
local subject recipients
subject="$1"
shift
recipients=("$@")
mail -a "Content-Type: text/plain; charset=UTF-8" -s "$subjsect" "${recipients[@]}"
}
mail_recipients=( "me@domain" "other@otherdomain" )
...
printf "%s\n" "$mail_text" | mail_cmd "$subject" "${mail_recipients[@]}"
笔记:
- 通常使用 UPPER_CASE_VARIABLES 从脚本导出变量,而不是本地变量。
- 您也可以导出函数。
我打印 $mail_cmd 是正确的
但是空间分离发生了,但"
引用解释没有。我的意思是这条线:
mail -a "Content-Type: text/plain; charset=UTF-8" -s "Backup script" me@domain
被解释为(添加单引号):
mail -a '"Content-Type:' 'text/plain;' 'charset=UTF-8"' -s '"Backup' 'script"' me@domain
mail
失败是因为前。text/plain
不是有效的邮件地址。
mail_text="$output\n\n退出状态码:$status"
这里\n
的不是换行符,而是字面上的\
斜线和n
n 字符。您可以使用简单的结构嵌入换行符,$'\n'
例如:
mail_text="$output"$'\n\n'"Exit status code: $status"
推荐阅读
- google-chrome-extension - chrome extension webRequest onBeforeRequest ( details.requestBody = error: "Unknown error." )
- vue.js - How to create vue file from component markup
- python - 在python中创建一个单词和数字密码
- ios - 使用 swift 4 将图像上传到服务器使用 Multi part & Alamofire
- asp.net-core - ASP Core 中的 ASP MVC 方法 Application_Start()
- python - 在 PyTorch 的 Dataloader 中使用带有腌制数据的生成器
- java - 如何在java中编写交错的通用工厂类
- c++ - 接受变量并返回一个元组进行变异
- opencv - 使用 Ubuntu 18.04 的 python3.6.x 和 opencv:找不到导入 cv2
- php - 如何从 Proto 规范中获取 PHP 的服务(服务器文件)?