是否可以使用 pysftp 模块删除包含某些内容的目录?

问题描述 投票:0回答:4

我正在使用 pysftp 模块创建备份脚本。我可以上传 并下载文件。当我尝试删除包含某些内容的目录时 内容我有一个例外。

这是我尝试过的

con = pysftp.Connection('192.168.0.40',username='root',password='clado123')
con.chdir('/root/backup')
con.pwd
con.listdir()
['data', 'test']
data - directory is not empty.
test - directory is empty.
con.rmdir('test')
con.listdir()
['data']
con.rmdir('data')

操作系统错误:失败

有人可以建议我一种解决这个问题的方法吗?

python python-2.7 python-3.x sftp pysftp
4个回答
8
投票

我已经找到办法了。 pysftp 连接对象中有一个名为“execute”的方法。我们可以使用此方法在远程服务器上执行命令。

con.execute('rm -rf /root/backup/data')
con.listdir()
[]

2
投票

其他解决方案取决于SFTP服务器操作系统。例如,如果 SFTP 服务器是 Windows 实现,则

con.execute('rm xxxx')
将不起作用。

对于仅使用 pysftp 删除非空目录的方法,您可以使用

con.walktree
递归删除所有常规文件,同时构建要在文件后面删除的子目录列表。

您不能直接删除

walktree
中的目录,因为它最后访问更深层次,而您需要相反的操作。

运行

walktree
后,您可以迭代(反向)目录列表和
rmdir
每个目录。

请注意,在下面的代码中

fcallback=con.remove
,因此 walktree 将为每个文件递归调用
remove(remotepath)

另一方面,

dcallback=dirs.append
因此对于每个目录将执行
dirs.append(directory_remote_path)
,有效地构建要删除的目录列表。

import os
import pysftp


sftp_host = os.environ[ 'SFTP_HOST' ]
sftp_username = os.environ[ 'SFTP_USERNAME' ]
sftp_password = os.environ[ 'SFTP_PASSWORD' ]

con = pysftp.Connection(sftp_host, username=sftp_username, password=sftp_password)

dirs = ['/root/backup/data']
con.walktree(dirs[0], fcallback=con.remove, dcallback=dirs.append, ucallback=con.remove, recurse=True)

print(dirs)

for d in reversed(dirs):
    print("Delete directory", d)
    con.rmdir(d)
    
con.close()



0
投票

remove
目录中的所有文件,然后使用
rmdir
删除空目录。对我有用。

def clean_dir(sftp, dir, files):
    assert sftp.isdir(str(dir)), "Outbox does not exist!"
    assert files.is_dir(), "Source directory does not exist!"
    for capsule in list(files.iterdir()):
        target = dir / capsule.name
        assert sftp.exists(str(target)), "Target files does not exist!"
        sftp.remove(str(target))
        assert not sftp.exists(str(target)), "Removed file still exists!"
© www.soinside.com 2019 - 2024. All rights reserved.