使用 Python 的 SCPClient 库在文件名中使用通配符

Ita*_*mon 4 python ssh scp paramiko

我想使用 Python 脚本将文件从远程机器复制到我的本地机器。我只知道文件名的扩展名,所以我想使用通配符来表示文件名。

此外,我想直接使用SCPClient Python 库而不是os.system,如题为using wildcards in filename in filename in python in python 中所建议的那样

但是当我运行以下代码时:

from paramiko import SSHClient
import paramiko
from scp import SCPClient

with SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('10.10.100.5', username= 'root', password='Secret')
    with SCPClient(ssh.get_transport()) as scp:
        scp.get(remote_path='/root/*.py', local_path='.')
Run Code Online (Sandbox Code Playgroud)

我得到一个例外

scp.SCPException: scp: /root/*.py: 没有那个文件或目录

从 shell 运行效果很好

scp root@10.10.100.5:/root/*.py 。

Han*_*nnu 12

您需要将 sanitize 添加到您的get_transport()

with SCPClient(ssh.get_transport(), sanitize=lambda x: x) as scp:
        scp.get(remote_path='/root/*.py', local_path='.')
Run Code Online (Sandbox Code Playgroud)

否则通配符按字面处理。

编辑 2020 年 9 月:对此答案有些困惑。上面的代码没有清理任何东西,但它提供了强制清理功能。Paramiko没有我们现在要关闭的默认消毒剂。无论发生或不发生清理,都必须来自实现,因为 Paramiko 无法知道哪些路径在您的特定环境中是安全的。

如果根本不存在清理功能,则所有通配符都按字面意思解释-出于安全原因,我假设通配符对于不受信任的输入是危险的。该设计通过添加某种清理功能来强制实现考虑清理。如果没有,通配符不能用作通配符。

为了使通配符起作用,需要有一个返回清理路径的清理函数。上面的 lambda 是一个虚拟函数,它返回输入给它的任何东西——这意味着它根本不做任何清理,但是因为现在有一个清理函数,通配符现在开始作为通配符工作。

如果您不信任您的输入,请不要这样做。在这种情况下,您需要编写适当的消毒剂以确保路径可以安全使用。您将需要编写一个返回清理路径的函数。

  • 为了澄清这个答案,您正在关闭清理功能,而不是实际添加它。这是通过将 sanitize 设置为一个函数来完成的,该函数基本上除了按原样返回值之外不执行任何操作。 (2认同)