Linux服務器配置了mailx 的郵箱客户端(參考:阿里雲配置CentOS郵箱mailx通過465端口發送郵件),使用的是騰訊企業郵箱

需求:

將備份腳本執行的過程輸出到日誌:back.log,並通過郵件發送到指定郵箱作為備份查閲。

cat back.log | mail -s "郵件主題" 收件人郵箱

問題:

發現有些備份腳本輸出的日誌,騰訊郵件讀不出正文,變成了附件的形式,如下:

Linux使用mailx發送郵件,正文變成了附件的形式:tcmime.xxxx.xxxx.xxxxx.bin_換行符

正常應該是如下顯示正文:

Linux使用mailx發送郵件,正文變成了附件的形式:tcmime.xxxx.xxxx.xxxxx.bin_換行符_02

問題原因:

騰訊郵箱設置發信,默認是以:Unicode編碼發信,在exmail.qq.com登錄後,設置-常規,下拉可以看到發信的設置

Linux使用mailx發送郵件,正文變成了附件的形式:tcmime.xxxx.xxxx.xxxxx.bin_rsync_03

之所以收到的日誌正文變成了附件,原因是:在發送的日誌正文中,有不能識別的字符編碼,郵箱客户端發送郵件後,在騰訊郵箱頁面不能識別這個字符編碼,才存入了附件。

目前發現騰訊郵箱-頁面、或者企業微信-郵件,會出現這樣的問題,但是使用foxmail客户端,啥問題沒有(果然老牌還是給力)

知道了原因,我們去查看不能識別的日誌文件:

Linux使用mailx發送郵件,正文變成了附件的形式:tcmime.xxxx.xxxx.xxxxx.bin_mail_04

正常cat 查看不出什麼異常,加上-v 看看,或者直接vim 打開

Linux使用mailx發送郵件,正文變成了附件的形式:tcmime.xxxx.xxxx.xxxxx.bin_mail_05

發現備份日誌中,出現了只有在DOS+/Windows+系統中才出現的換行符^M, 這是我備份時使用了rsync -avzP ... > back.log出現的

rsync 的 -P 參數結合了 --partial 和 --progress,會在傳輸過程中持續更新進度條(如顯示已傳輸文件數、進度百分比等)。

為了實現實時更新,rsync 會輸出回車符(\r)將光標移回行首,然後重寫當前行內容,而非生成新行。如果終端或日誌解析器未能正確處理這種回車符序列(如將 \r\n 誤作普通文本),^M 就會直接顯示出來


\r\n 是 DOS/Windows 環境才會使用的換行符

Unix/Liunx\n

解決辦法:

參考了其他網友的方法(好用的不好用的我都試了),這裏整理一下:

原則就是去掉^M,也就是rsync的\r回車符

1、調整rsync參數

既然知道了問題在哪裏,而且我也不是非要查看同步進度,直接改為靜默模式

rsync -avz ... > back.log

2、過濾回車符

日誌在重定向時,直接通過管道符|處理回車符\r,只不過,這樣處理的話,-P的進度特性會輸出很多的日誌,自己體會哈

rsync -avzP ... | tr -d '\r' > back.log # 直接刪除會把進度打印成一行
或者
rsync -avzP ... | tr -s '\r' '\n' > back.log # 替換成Linux換行符,會友好展示

3、sed處理(寫腳本最合適)

sed -i 's/\r/\n/g' back.log

4、其它場景:

如果有其它場景,不是rsync產生的^M,可能是純windows生成的文本,字符編碼不對,可以試試dos2unix,我沒有這個場景所有沒試過這個工具

#yum install dos2unix -y

#dos2unix  /tmp/file.txt

總結:

只要我們知道了原理,解決辦法就出來了,日常用到mail的地方也很多,比如一些報警功能(腳本、zabbix、prometheus),或者程序調用等等

無外乎就是字符編碼不匹配,或不識別,修改的方法多種多樣,歡迎大家留言探討!