(转载)记录一奇葩scp问题的分析与解决过程

引 入

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


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

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

[root@172.16.13.62 ~]#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文件剩下的字节将会在屏幕显示出来。

[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打印的话。


是不是挺有意思呢?

由于问题已经解决,自己又没很大决心再往细细去研究这SCP的工作原理,所以我的分析就到此为止了。想深入了解SCP原理的朋友可以参考How the SCP protocol works这篇文件,写得还不错。

三、补充:bash的配置文件类型
主要可以分为两类:
profile类:为交互式登录的shell进程提供配置
bashrc类:为非交互式登录的shell进程提供配置

  • 登录类型:

    • 交互式登录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/*

原文地址

2016-03-17 15:1915