SCP拷贝失败解决办法
1. 现象:
今天在提交代码的时候,提示hooks文件不存在,需要下载。
我之前用scp -p -P 1111 xxxx@gerrit.xxxx:hooks/commit-msg$(gitdir)/hooks/ 就能下载,
但是更新系统后下载失败,显示
subsystem request failed on channel 0
scp: Connection closed
所以查了一下原因。
2. 分析:
2.1. 在stack上前辈提示加一个-O即可解决该问题,试了一下果然可以下载
2.2. 继续查了一下scp的参数-O作用:-O
(legacy SCP protocol): 强制 scp
使用传统的 SCP 协议而不是现代的 SFTP 子系统。SCP 协议是通过 SSH 直接执行远程 scp
命令来实现的,不依赖于 SFTP 子系统,因此可以绕过某些服务器的子系统限制(例如 subsystem request failed on channel 0
的错误)。
2.3. 查了一下scp新老协议的区别:
2.3.1. 实现方式
-
旧的 SCP 协议:
- 基于
rcp
(remote copy protocol),通过直接在远程服务器上执行scp
命令来传输文件。 - 不使用 SFTP 子系统,直接通过 SSH 命令发送和接收文件。
- 传输时的文件路径和权限会作为明文参数传递,较为简单。
- 由于是基于旧协议,功能较为有限,且错误处理和交互反馈较差。
- 基于
-
新的 SCP 协议(基于 SFTP 子系统):
- 使用 SSH 的 SFTP 子系统进行文件传输,通常比旧协议更加安全和可靠。
- 支持更多文件操作(如文件夹传输、符号链接处理等),并且可以更好地处理复杂路径和文件权限。
- 提供了更好的错误处理机制,传输失败时可以给出更详细的错误信息。
- 更容易与其他基于 SFTP 的工具集成,如 GUI 文件管理器。
2.3.2. 安全性
-
旧的 SCP 协议:
- 存在一些已知的安全问题,比如可能会被服务器端恶意篡改,导致客户端错误地保存或覆盖文件。
- 对于某些特殊字符处理不当,可能被用于命令注入攻击。
- 对文件名和路径缺乏严格的检查,因此在某些环境中可能会出现未预期的行为。
-
新的 SCP 协议:
- 由于基于 SFTP,采用的是更成熟和安全的文件传输机制,避免了许多旧协议的安全漏洞。
- 对文件名、路径和权限有更严格的验证,防止意外的错误操作和安全风险。
- 支持现代加密标准,并且容易与现代 SSH 配置进行集成和优化。
2.3.3. 功能和扩展性
-
旧的 SCP 协议:
- 功能简单,主要用于单纯的文件复制,不支持文件夹的递归拷贝、符号链接的处理、扩展文件属性等。
- 错误信息简陋,调试和故障排除较为困难。
-
新的 SCP 协议:
- 提供更丰富的功能,支持递归文件夹传输、文件属性保持、符号链接等复杂操作。
- 错误反馈更详细,可以帮助用户更容易找到问题所在。
2.3.4. 总结
旧的 SCP 协议因为其简单性和低性能开销在某些场合仍有使用价值,尤其是在不支持 SFTP 的系统或受限环境下。而新的基于 SFTP 的 SCP 协议则在安全性、功能性和用户体验方面有显著提升,是目前的推荐方式。使用 -O
选项可以强制 SCP 回到旧模式,以应对兼容性问题。
2.3.5 怎么区分新协议还是老协议
可以打印scp的日志,在scp后加入-v参数,查看有没有"sending subsystem:sftp”,如果有则是新协议。