Linux/UNIX Shell脚本:数据库结果用于邮件报告的循环处理问题
Bash脚本处理MySQL查询结果生成邮件报告方案
嘿,我来帮你解决这个从数据库取数生成邮件报告的问题~首先得指出你原来的写法里有个小坑:直接把MySQL查询结果塞进数组results=($(...))会因为公司名称里的空格(比如“Google India”)导致数组元素被错误拆分,本来一行3个字段会变成4个元素,循环处理的时候肯定会乱套。
下面给你两种靠谱的解决方案,都是专门处理带空格字段的场景:
方案一:直接管道循环读取(推荐,简洁高效)
利用MySQL的-B参数输出制表符分隔的字段,再结合IFS=$'\t'让read命令正确识别字段边界,完美处理带空格的公司名称:
#!/bin/bash # 先定义好数据库连接信息(建议用~/.my.cnf存密码,更安全,后面会说) DB_USER="your_db_user" DB_PWD="your_db_password" DB_NAME="your_database" # 初始化邮件主题和正文 EMAIL_SUBJECT="本月客户账单报告" EMAIL_BODY="=== 本月账单详情 ===\n\n" EMAIL_BODY+="公司名称\t\t城市\t账单金额\n" EMAIL_BODY+="-------------------------------\n" # 执行查询并逐行处理结果 mysql --user "${DB_USER}" -p"${DB_PWD}" "${DB_NAME}" -Bse "select company_name,City,bill_amount from myTable;" | while IFS=$'\t' read -r company city amount; do # 把每行数据追加到邮件正文 EMAIL_BODY+="${company}\t${city}\t${amount}\n" done # 发送邮件(这里用mailx,不同系统可能用mail或sendmail,按需调整) echo -e "${EMAIL_BODY}" | mailx -s "${EMAIL_SUBJECT}" report-recipient@yourcompany.com
关键细节说明:
-B:让MySQL以批处理模式输出,字段间用制表符分隔,避免空格干扰IFS=$'\t':告诉read命令用制表符作为字段分隔符,这样带空格的公司名称会被完整读取-r:防止read把反斜杠当作转义字符,避免意外解析问题
方案二:先把结果存入数组再处理
如果一定要用数组存储结果,可以用mapfile(或readarray)把每行结果作为数组的一个元素,之后再循环拆分每行的字段:
#!/bin/bash # 数据库连接信息同上 DB_USER="your_db_user" DB_PWD="your_db_password" DB_NAME="your_database" # 把查询的每一行存入数组results mapfile -t results < <(mysql --user "${DB_USER}" -p"${DB_PWD}" "${DB_NAME}" -Bse "select company_name,City,bill_amount from myTable;") # 初始化邮件内容 EMAIL_SUBJECT="本月客户账单报告" EMAIL_BODY="=== 本月账单详情 ===\n\n" EMAIL_BODY+="公司名称\t\t城市\t账单金额\n" EMAIL_BODY+="-------------------------------\n" # 循环处理数组中的每一行 for row in "${results[@]}"; do # 拆分当前行的字段 IFS=$'\t' read -r company city amount <<< "$row" # 追加到邮件正文 EMAIL_BODY+="${company}\t${city}\t${amount}\n" done # 发送邮件 echo -e "${EMAIL_BODY}" | mailx -s "${EMAIL_SUBJECT}" report-recipient@yourcompany.com
安全提示:
命令行里直接写密码-p${DB_PWD}有安全风险(会被ps命令查到),建议把数据库连接信息放到~/.my.cnf文件里:
[client] user=your_db_user password=your_db_password database=your_database
之后执行MySQL命令就可以简化成:mysql -Bse "select ...",既安全又简洁。
内容的提问来源于stack exchange,提问作者Arpit Awasthi
相关产品推荐
相关产品推荐

