我正在尝试使用 SCP 命令将文件从本地主机复制到远程主机:
scp -v [email protected]:/local/file/path /destination/path
令人惊讶的是,经过密码验证后,SCP 命令最终失败。我能够通过 SSH 连接到远程系统,但 SCP 失败。这是我最后得到的错误。
debug1: rekey after 4294967296 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey after 4294967296 blocks
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: password
debug1: Next authentication method: password
[email protected]'s password:
debug1: Authentication succeeded (password).
Authenticated to 192.168.1.12 ([192.168.1.12]:22).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: pledge: network
debug1: Sending command: scp -v -f /home/random/sample.txt
Sink: C0777 630 /home/random/sample.txt
error: unexpected filename: /home/random/sample.txt
失败的原因是什么,我已经验证了源文件存在。我无法理解这个错误消息是什么意思Sink: C0777 630
答案1
简而言之,远程系统上的 scp 软件似乎正在发送无效的协议消息。您应该联系软件供应商寻求支持。
Sink: C0777 630 /home/random/sample.txt
error: unexpected filename: /home/random/sample.txt
“sink” 消息不是错误。它只是一条消息,给出从远程系统收到的 SCP 协议命令。您收到“sink”消息是因为您正在scp
以详细模式运行。此特定消息表示远程系统正在发送一个文件(“C”),其权限为 0777,大小为 630 字节,文件名为“/home/random/sample.txt”。
“错误”消息表明 SCP 协议命令存在问题。问题是scp
您在本地端使用的 OpenSSH 程序不接受包含“/”字符的文件名。
当我运行类似的 scp 命令时,会发生以下情况:
$ scp -v localhost:/etc/services .
...
debug1: Sending command: scp -v -f /etc/services
Sending file modes: C0644 677972 services
Sink: C0644 677972 services
请注意,“sink”行中的文件名部分不是完整的路径名,只是正在发送的文件的基本名称。
您指出远程系统正在运行来自利基市场。您应该联系这家公司寻求支持。据我所知,SCP 协议没有正式的标准,甚至很难在互联网上找到该协议的良好描述。我认为可以公平地说,大多数人会考虑OpenSSH版本作为scp
事实上的标准,并期望其他 scp 实现能够与 OpenSSH 互操作。
答案2
您的远程端以某种方式实现了 SCP“协议”,该协议与scp
您通常在 Linux 或 BSD 机器上发现的 OpenSSH 实现不兼容。
在阅读了 OpenSSH scp
、BSDrcp
和 Putty的代码pscp
(见下文)后,似乎必须仔细阅读源代码才能理解 SCP 是正常的。此存档网页说:
您是否曾经想过 scp 和 rcp 命令是如何工作的?我第一次这样做时,没有找到有关该主题的任何文档。没有 RFC,没有草稿,甚至没有描述它的 README 文件。阅读源代码后,我再次尝试并意识到旧版本的 rcp.c 可能确实是唯一可用的原始文档。
(Jan Pechanec 的博客:“SCP 协议如何运作”,摘自 2017 年 2 月 15 日)
使用上面页面的解释和你的命令
scp -v [email protected]:/local/file/path /destination/path
这意味着你从远程系统复制内容(利基市场 scp
(处于“源”模式)到您的系统(可能是 OpenSSH scp
,处于“接收器”模式)。
然而,远程系统在 SCP 协议下进行交换时会为您提供多个目录的路径:
C0777 630 /home/random/sample.txt
<data of sample.txt>
而你scp
只能处理类似这样的事情:
D0755 0 home
D0755 0 random
C0777 630 sample.txt
<data of sample.txt>
E
E
解决方案是检查scp
本地系统上是否有不同的实现,或者尝试sftp
:
sftp -q [email protected]:/remote/file/path /local/destination/path
我最初的回答,后来更新:
接收器:C0777 630 /home/random/sample.txt
它似乎起源于scp
。
例如你可以看看在第 969 行,这是最新版本的OpenSSH由使用FreeBSD。
if (verbose_mode)
fmprintf(stderr, "Sink: %s", buf);
翻译:如果处于详细模式,则显示“Sink:”消息,其中字符串指向buf
您提供了 -v 选项。
它似乎显示剩余的缓冲区。C0777
似乎是一个 BSDrcp
命令,请参阅标题
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
和1023 行。
这个
错误:意外的文件名:/home/random/sample.txt
由撰写1051 行:
if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) {
run_err("error: unexpected filename: %s", cp);
exit(1);
翻译:如果指向的字符串cp
包含斜杠(/
)字符或等于字符串,..
则打印错误消息。您的字符串中有一条斜线。
看起来它并scp
没有从与远程实例的对话中获得期望的结果ssh
。
更新:
Sink
是呼叫的对方Source
。这里我们有来自 OpenSSH 实现的另一面:
snprintf(buf, sizeof buf, "C%04o %lld %s\n",
(u_int) (stb.st_mode & FILEMODEMASK),
(long long)stb.st_size, last);
从之前的代码可以清楚的看出这三个参数分别是文件模式(权限位)、文件大小和文件名。同样,文件名不能包含斜杠,否则被忽略。
它看起来像目录树被递归遍历,并且只处理遍历级别的名称。
顺便说一句,OpenSSH 中的代码scp
看起来确实很老了,引用的内容已经在 BSD 4.xrcp
实现中了。请参阅这里。
查看pscp
实施情况(Putty scp)这里我们可以识别 BSD 内容(参见第 1524 行),但文件名处理不同。这就是它起作用的原因。
答案3
我的情况是
.bashrc
在非交互模式下打印东西(这是不正确的)
快速检查
ssh YOUR_SERVER echo -n | hd
## or
ssh YOUR_SERVER true | hd
不应输出任何内容
或者尝试
$ scp -s YOUR_SERVER:.bashrc .
scp: Received message too long 459092027
scp: Ensure the remote shell produces no output for non-interactive sessions.
解决(这种情况)
我在开头添加了这个.bashrc
,问题解决了
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac