引 入
linux是一個龐大複雜的系統。整天跟它打交道的運維或開發人員難免不遇到什麼問題。這裏,本人聊聊遇到的一個跟scp相關的奇葩問題。
一、問題描述
兩臺centos6.7主機(主機一:172.16.13.62和主機二:172.16.13.72),都安裝好ssh,相關的ssh連接配置也沒問題,但是在用scp進行兩主機之間的文件傳輸複製時,出現以下情況:
在主機一上操作scp,成功從主機二傳輸文件到主機一。當然也能成功把文件從主機一成功傳輸到主機二。如:
[[email protected] ~]#scp 172.16.13.72:/root/20160215.log /root [email protected]'s password: 20160215.log 100% 3434 3.4KB/s 00:00 [[email protected] ~]#
而在主機二上操作scp,做從主機一傳輸文件到主機二時,成功輸入密碼後,出現如下情況:
[[email protected] ~]#scp 172.16.13.62:/root/20160215.log /root [email protected]'s password: ---------change alias here----------- [[email protected] ~]#
打印了一句"change alias here",然後就結束了,scp沒有成功傳輸文件。當然從主機二傳輸文件到主機一的時候,依舊也是打印一句"change alias here",傳輸也是沒有成功的。
爲什麼在主機一上操作scp成功,而在主機二上操作卻不成功呢?那句"change alias here"又是從哪裏來的呢?我做出了以下分析:
二、分析解決
以下分析中,主機二也叫錯誤主機,主機一成爲正確主機。
步驟:
1) 通過scp -v查看錯誤主機的debug詳細信息
[[email protected] ~]#scp -v 172.16.13.62:/root/20160215.log /root
從debug中可以看出這次scp的運行的結果狀態是有錯誤的,但是不容易發現錯誤點在哪,所以我在正確主機上也debug來對比分析。
2) 對比正確主機分析錯誤
[[email protected] ~]#scp -v 172.16.13.72:/root/20160215.log /root
從debug中可以看出這次scp的運行的結果狀態是有正確的。對比過後分析後可以大概把錯誤點定位在"Send file modes 跟Sink"這兩個入口。
3) 分析出現"change alias here"的地方
由於發現"change alias here"是在非交互式登錄時就會出現,故很快可以找出"change alias here"的所在地。即:~/.bashrc
發現原來是前面爲了標識一下可以在~/.bashrc中定義命令別名而加上的一句echo回顯打印。把相關的echo刪除後可以發現scp可以正常操作,問題解決。
4) 回頭分析錯誤出現深一步原因
多一個echo就會出現scp錯誤?通過查閱各種相關資料得知,基於ssh的scp命令的工作模式主要有source mode跟sink mode兩種,建立連接後。
如果請求方接收到的第一個字符不是大寫字符"C",如上面例子的"---------change alias here-----------"。則會由於這遠端shell的配置文件輸出“加入”的協議會話而退出了scp。
如果請求方接收到的第一個字符是大寫字符"C",如"C0644 3334 20160215.log",你就會發現一個有趣的情況,scp程序將會成功讀取3334個字節,20160215.log文件剩下的字節將會在屏幕顯示出來。
[[email protected] ~]# scp 172.16.13.62:20160215.log . [email protected]'s password: 20160215.log 100% 3334 3.3KB/s 00:00 6/index.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36" [[email protected] ~]#
而讀取到的20160215.log文件裏面,會包含“C0644 3334 20160215.log”這句echo打印的話。
是不是挺有意思呢?
由於問題已經解決,自己又沒很大決心再往細細去研究這SCP的工作原理,所以我的分析就到此爲止了。想深入瞭解SCP原理的朋友可以參考How the SCP protocol works這篇文件,寫得還不錯。
三、補充:bash的配置文件類型
主要可以分爲兩類:
profile類:爲交互式登錄的shell進程提供配置
bashrc類:爲非交互式登錄的shell進程提供配置
全局:對所有用戶都生效 | 用戶個人:僅對當前用戶有效 | 功用 | |
profile類 | /etc/profile 或 /etc/profile.d/*.sh | ~/.bash_profile | 1、定義環境變量; 2、運行命令或腳本 |
bashrc類 | /etc/bashrc | ~/.bashrc | 1、定義本地變量; 2、定義命令別名; |
登錄類型:
交互式登錄shell進程:
直接通過某終端輸入賬號和密碼後登錄打開的shell進程;
使用su命令:su - USERNAME, 或者使用 su -l USERNAME執行的登錄切換;
非交互式登錄shell進程:
su USERNAME執行的登錄切換;
圖形界面下打開的終端;
運行腳本
配置文件讀取順序:
交互式登錄shell進程:
/etc/profile --> /etc/profile.d/* --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登錄shell進程:
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*
結 語
發現問題不可怕,解決問題時,分析思路最重要。
如果朋友你自己也有linux相關的奇葩問題,不要一個人留着哦,期待與您一起討論分享。
附:如對上面描述有疑問,期待與朋友您共同探討。本人QQ:1084569767