引 入        


       linux是一个庞大复杂的系统。整天跟它打交道的运维或开发人员难免不遇到什么问题。这里,本人聊聊遇到的一个跟scp相关的奇葩问题。


一、问题描述



    两台centos6.7主机(主机一:172.16.13.62和主机二:172.16.13.72),都安装好ssh,相关的ssh连接配置也没问题,但是在用scp进行两主机之间的文件传输复制时,出现以下情况:

    在主机一上操作scp,成功从主机二传输文件到主机一。当然也能成功把文件从主机一成功传输到主机二。如:

[root@172.16.13.62 ~]#scp 172.16.13.72:/root/20160215.log /root
root@172.16.13.72's password: 
20160215.log                                     100% 3434     3.4KB/s   00:00    
[root@172.16.13.62 ~]#

    而在主机二上操作scp,做从主机一传输文件到主机二时,成功输入密码后,出现如下情况:

[root@172.16.13.72 ~]#scp 172.16.13.62:/root/20160215.log /root
root@172.16.13.62's password: 
---------change alias here-----------
[root@172.16.13.72 ~]#

    打印了一句"change alias here",然后就结束了,scp没有成功传输文件。当然从主机二传输文件到主机一的时候,依旧也是打印一句"change alias here",传输也是没有成功的。

    为什么在主机一上操作scp成功,而在主机二上操作却不成功呢?那句"change alias here"又是从哪里来的呢?我做出了以下分析:

 

二、分析解决


    

以下分析中,主机二也叫错误主机,主机一成为正确主机。

步骤:

1) 通过scp -v查看错误主机的debug详细信息

[root@172.16.13.72 ~]#scp -v 172.16.13.62:/root/20160215.log /root

wKiom1bRLDuyBhNSAABNATRxhbE108.png

    从debug中可以看出这次scp的运行的结果状态是有错误的,但是不容易发现错误点在哪,所以我在正确主机上也debug来对比分析。


2) 对比正确主机分析错误

[root@172.16.13.62 ~]#scp -v 172.16.13.72:/root/20160215.log /root

wKiom1bRLuziMmrMAABQDl_YZEU270.png

    从debug中可以看出这次scp的运行的结果状态是有正确的。对比过后分析后可以大概把错误点定位在"Send file modes 跟Sink"这两个入口。


3) 分析出现"change alias here"的地方

    由于发现"change alias here"是在非交互式登录时就会出现,故很快可以找出"change alias here"的所在地。即:~/.bashrc

wKioL1bRMzCAEVqiAAAi9g0JA2U027.png

    发现原来是前面为了标识一下可以在~/.bashrc中定义命令别名而加上的一句echo回显打印。把相关的echo删除后可以发现scp可以正常操作,问题解决。


4) 回头分析错误出现深一步原因

    多一个echo就会出现scp错误?通过查阅各种相关资料得知,基于ssh的scp命令的工作模式主要有source modesink mode两种,建立连接后。

    如果请求方接收到的第一个字符不是大写字符"C",如上面例子的"---------change alias here-----------"。则会由于这远端shell的配置文件输出“加入”的协议会话而退出了scp。

    如果请求方接收到的第一个字符是大写字符"C",如"C0644 3334 20160215.log",你就会发现一个有趣的情况,scp程序将会成功读取3334个字节,20160215.log文件剩下的字节将会在屏幕显示出来。

[root@172.16.13.72 ~]# scp 172.16.13.62:20160215.log  .
root@172.16.13.62'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"
[root@172.16.13.72 ~]#

    而读取到的20160215.log文件里面,会包含“C0644 3334 20160215.log”这句echo打印的话。

wKiom1bRSNmwaWUBAABRaOkJWSg790.png

    是不是挺有意思呢?

    

    由于问题已经解决,自己又没很大决心再往细细去研究这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