我使用SFTP服务器备份数据库和整个网站结构。由于使用了糟糕的脚本,导致在SFTP服务器上出现了重复文件。我尝试使用rmdir文件夹
命令删除这些文件,但是却遇到了错误。
Couldn't remove directory: Failure
如果我理解正确,在SFTP中只有当文件夹为空时才能删除该文件夹。如果我使用代码rm folder/*
,则不会删除内部文件夹。
那么我有没有其他方法可以做到这一点呢?
你也可以使用以下方法挂载远程目录:
sshfs user@yourdomain.com:/path/to/remote local/path
那么只需使用 cd local/path
命令,然后您就可以自由地使用rm -r folder
命令。
itdxer的解决方案非常好,但它并不会删除所有内容:如果子文件夹原本不为空,它只会删除子文件夹的内容。同时,也可以通过结合isdir和rm来缩短代码。
def rm(path):
files = sftp.listdir(path)
for f in files:
filepath = os.path.join(path, f)
try:
sftp.remove(filepath)
except IOError:
rm(filepath)
sftp.rmdir(path)
os.path.join()
可能无法在跨系统时生成正确的路径。在 Windows 上运行此脚本并针对 Linux 服务器,会生成诸如 /tmp/dev\\afile.txt
的路径,导致脚本崩溃。最终我使用了 '/'.join(...)
,虽然不是普遍正确的方法,但在目标系统为 Linux 时可以使用。 - WoJnot is_dir()
然后 remove()
,我们将向远程 SFTP 发送两个请求,而不是在成功删除时发送单个请求(如果它是一个目录,我们对两种方法都有相同数量的请求)。更重要的是,EAFP 方法允许我们原子地删除文件:没有第三方会在我们执行 is_dir()
和 remove()
之间更改任何内容。我们应该在每种具体情况下务实,但在这种情况下,仅出于上述原因,我个人更喜欢 EAFP。 - Mikhail Gerasimov在Python中实现简单的解决方案。我认为这将有助于未来的工作。
import os
import paramiko
from stat import S_ISDIR
server ="any.sftpserver"
username = "uname"
password = "***"
path_to_hosts_file = os.path.join("~", ".ssh", "known_hosts")
ssh = paramiko.SSHClient()
ssh.load_host_keys(os.path.expanduser(path_to_hosts_file))
ssh.connect(server, username=username, password=password)
def isdir(path):
try:
return S_ISDIR(sftp.stat(path).st_mode)
except IOError:
return False
def rm(path):
files = sftp.listdir(path=path)
for f in files:
filepath = os.path.join(path, f)
if isdir(filepath):
rm(filepath)
else:
sftp.remove(filepath)
sftp.rmdir(path)
if __name__ == "__main__":
rm("/path/to/some/directory/to/remove")