Linux服務器配置了mailx 的郵箱客户端(參考:阿里雲配置CentOS郵箱mailx通過465端口發送郵件),使用的是騰訊企業郵箱
需求:
將備份腳本執行的過程輸出到日誌:back.log,並通過郵件發送到指定郵箱作為備份查閲。
cat back.log | mail -s "郵件主題" 收件人郵箱
問題:
發現有些備份腳本輸出的日誌,騰訊郵件讀不出正文,變成了附件的形式,如下:
正常應該是如下顯示正文:
問題原因:
騰訊郵箱設置發信,默認是以:Unicode編碼發信,在exmail.qq.com登錄後,設置-常規,下拉可以看到發信的設置
之所以收到的日誌正文變成了附件,原因是:在發送的日誌正文中,有不能識別的字符編碼,郵箱客户端發送郵件後,在騰訊郵箱頁面不能識別這個字符編碼,才存入了附件。
目前發現騰訊郵箱-頁面、或者企業微信-郵件,會出現這樣的問題,但是使用foxmail客户端,啥問題沒有(果然老牌還是給力)
知道了原因,我們去查看不能識別的日誌文件:
正常cat 查看不出什麼異常,加上-v 看看,或者直接vim 打開
發現備份日誌中,出現了只有在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),或者程序調用等等
無外乎就是字符編碼不匹配,或不識別,修改的方法多種多樣,歡迎大家留言探討!