为什么使用 SCP 命令时会出现“Sink”错误?

为什么使用 SCP 命令时会出现“Sink”错误?

我正在尝试使用 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

參考文獻:
https://forums.centos.org/viewtopic.php?t=4090#p20164

相关内容