如何在Python中删除远程SFTP服务器上目录中的所有文件?

16

我想删除已连接到的远程服务器上给定目录中的所有文件,使用Paramiko。然而,我无法显式地给出文件名,因为这将取决于我之前放置在那里的文件版本。

以下是我正在尝试的内容... #TODO下面的行是我尝试的调用,其中remoteArtifactPath类似于/opt/foo/*

ssh = paramiko.SSHClient()
ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
ssh.connect(server, username=username, pkey=mykey)
sftp = ssh.open_sftp()

# TODO: Need to somehow delete all files in remoteArtifactPath remotely
sftp.remove(remoteArtifactPath+"*")

# Close to end
sftp.close()
ssh.close()

有什么想法可以实现这个吗?

6个回答

21
我找到了一个解决方案:遍历远程位置中的所有文件,然后对每个文件调用remove函数。
ssh = paramiko.SSHClient()
ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
ssh.connect(server, username=username, pkey=mykey)
sftp = ssh.open_sftp()

# Updated code below:
filesInRemoteArtifacts = sftp.listdir(path=remoteArtifactPath)
for file in filesInRemoteArtifacts:
    sftp.remove(remoteArtifactPath+file)

# Close to end
sftp.close()
ssh.close()

7
建议使用os.path.join(remoteArtifactPath, file)代替sftp.remove(remoteArtifactPath+file), 因为os.path.join()是跨平台的。行分隔符在不同平台上可能不同,使用os.path.join可以确保生成正确的路径,而不受平台影响。 - 9monkeys
这会同时移除隐藏文件吗? - SabirAmeen

11

你需要一个递归程序,因为你的远程目录可能有子目录。

def rmtree(sftp, remotepath, level=0):
    for f in sftp.listdir_attr(remotepath):
        rpath = posixpath.join(remotepath, f.filename)
        if stat.S_ISDIR(f.st_mode):
            rmtree(sftp, rpath, level=(level + 1))
        else:
            rpath = posixpath.join(remotepath, f.filename)
            print('removing %s%s' % ('    ' * level, rpath))
            sftp.remove(rpath)
    print('removing %s%s' % ('    ' * level, remotepath))
    sftp.rmdir(remotepath)

ssh = paramiko.SSHClient()
ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
ssh.connect(server, username=username, pkey=mykey)
sftp = ssh.open_sftp()
rmtree(sftp, remoteArtifactPath)

# Close to end
stfp.close()
ssh.close()

7
一个 Fabric 程序可以非常简单,就像这样:

一个Fabric例程可能就是这样的:

with cd(remoteArtifactPath):
    run("rm *")

Fabric非常适合在远程服务器上执行shell命令。实际上,Fabric底层使用的是Paramiko,因此如果需要,可以同时使用两者。


+1,因为在EC2中,我们的操作系统映像默认情况下禁用了sftp。(我不确定这是亚马逊的默认设置还是我的公司的设置,但这个问题并不重要,因为我无法更改它。然而,我仍然需要删除该文件。) - Scott Prive

2
我找到了一个解决方案,使用 Python3.7Spur 0.3.20。很可能也适用于其他版本。原始答案翻译成"我找到了一个解决方案,使用Python3.7和Spur 0.3.20。很可能也适用于其他版本。"
import spur

shell = spur.SshShell( hostname="ssh_host", username="ssh_usr", password="ssh_pwd")
ssh_session = shell._connect_ssh()

ssh_session.exec_command('rm -rf  /dir1/dir2/dir3')

ssh_session.close()

2

对于@markolopa的答案,您需要导入2个模块才能使其正常工作:

import posixpath
from stat import S_ISDIR

0

我知道这是一篇较早的帖子,但我仍然想给出一个简短的答案,我发现它比其他答案更有用。此外,这个方法使用了paramiko的内置函数,所以应该适用于所有设备。

import paramiko

class remote_operations:
    def __init__(self):
        pass
    
    def connect(self, hostname, username, password):
        client = paramiko.SSHClient()
        client.load_system_host_keys()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(hostname, username=username, password=password)
        return client

def delete_files():
    print("--Deleting files--")
    test = remote_operations()

    # these ips and passwords are just examples
    username = "aabfbkbakjdfb123"
    password = "I_am_not_good_at_making_passwords_123"
    host_ip = "111.111.11.11"

    client = test.connect(host_ip,username,password)
    sftp_client = client.open_sftp()

    folderPath = "/my_secret_files/"
    sftp_client.chdir(folderPath)

    for file in sftp_client.listdir():
        sftp_client.remove(file)

if __name__ == '__main__':
    delete_files()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接