scp fails with "protocol error: filename does not match request"

scp fails with "protocol error: filename does not match request"

我有一个使用 SCP 从 AWS 上的远程 Linux 主机拉取文件的脚本。在 运行 每晚使用相同的代码大约 6 个月没有问题后,它今天开始失败 protocol error: filename does not match request。我在下面的一些更简单的文件名上重现了这个问题:

$ scp -i $IDENT $HOST_AND_DIR/"foobar" .
# the file is copied successfully

$ scp -i $IDENT $HOST_AND_DIR/"'foobar'" .
protocol error: filename does not match request
# used to work, i swear...

$ scp -i $IDENT $HOST_AND_DIR/"'foobarbaz'" .
scp: /home/user_redacted/foobarbaz: No such file or directory
# less surprising...

我使用单引号的原因是我最初抓取的是名称中包含空格的文件。为了处理空格,我做了$HOST_AND_DIR/"'foo bar'"好几个月了,但是从今天开始,它只接受$HOST_AND_DIR/"foo\ bar"。所以,我的问题 修复,但我仍然很好奇发生了什么。

我用 Google 搜索了错误消息,但我没有看到任何真正提及它的内容,这让我很吃惊。

所涉及的两个主机在 ssh -v localhost 的输出中都有 OpenSSL 1.0.2g,并且 bash --version 表示 GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu) 有什么想法吗?

我最终查看了源代码并找到了抛出此错误的提交:

GitHub Commit

remote->local directory copies satisfy the wildcard specified by the user.

This checking provides some protection against a malicious server sending unexpected filenames, but it comes at a risk of rejecting wanted files due to differences between client and server wildcard expansion rules.

For this reason, this also adds a new -T flag to disable the check.

他们添加了一个新标志 -T,它将忽略他们添加的这项新检查,因此它是向后兼容的。但是,我想我们应该查看并找出为什么我们使用的文件名被标记为受限。

就我而言,我的文件名中有 [] 个字符需要使用 here 列出的选项之一进行转义。例如:

scp root@IP_ADDR:"/tmp/foo\[bar\].txt" /tmp