Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中通过SFTP连接后列出目录中的所有文件夹和文件_Python_Ssh_Sftp_Paramiko - Fatal编程技术网

如何在Python中通过SFTP连接后列出目录中的所有文件夹和文件

如何在Python中通过SFTP连接后列出目录中的所有文件夹和文件,python,ssh,sftp,paramiko,Python,Ssh,Sftp,Paramiko,我正在使用Python并尝试连接到SFTP,希望从那里检索XML文件,并需要将其放在本地系统中。代码如下: import paramiko sftpURL = 'sftp.somewebsite.com' sftpUser = 'user_name' sftpPass = 'password' ssh = paramiko.SSHClient() # automatically add keys without requiring human intervention ssh.

我正在使用Python并尝试连接到SFTP,希望从那里检索XML文件,并需要将其放在本地系统中。代码如下:

import paramiko

sftpURL   =  'sftp.somewebsite.com'
sftpUser  =  'user_name'
sftpPass  =  'password'

ssh = paramiko.SSHClient()
# automatically add keys without requiring human intervention
ssh.set_missing_host_key_policy( paramiko.AutoAddPolicy() )

ssh.connect(sftpURL, username=sftpUser, password=sftpPass)

ftp = ssh.open_sftp()
files = ftp.listdir()
print files
这里的连接是成功的。现在我想查看所有的文件夹和文件,并且需要进入所需的文件夹,以便从那里检索XML文件

最后,我打算在连接到SFTP服务器后查看所有文件夹和文件

在上面的代码中,我使用了
ftp.listdir()
,通过它我获得了如下输出

['.bash_logout', '.bash_profile', '.bashrc', '.mozilla', 'testfile_248.xml']
我想知道是否只有这些文件

我上面使用的命令也可以查看文件夹吗


查看所有文件夹和文件的命令是什么?

一个快速解决方案是检查
ftp.listdir()中每个对象的
lstat
输出

以下是如何列出所有目录

>>> for i in ftp.listdir():
...     lstatout=str(ftp.lstat(i)).split()[0]
...     if 'd' in lstatout: print i, 'is a directory'
... 
文件与搜索相反:

>>> for i in ftp.listdir():
...     lstatout=str(ftp.lstat(i)).split()[0]
...     if 'd' not in lstatout: print i, 'is a file'
... 
返回所有内容、文件和文件夹

如果有文件夹,要从文件中分辨出来,请改用。它返回一个集合


@Oz123接受的答案效率低下
SFTPClient.listdir
内部调用
SFTPClient.listdir\u attr
并丢弃大部分信息,只返回文件和文件夹名称。然后,通过为每个文件调用
SFTPClient.lstat
,答案将徒劳地重新检索所有数据

另见



强制性警告:不要使用
AutoAddPolicy
–这样做会失去保护。要获得正确的解决方案,请参阅。

这是我提出的一个解决方案。基于。我的解决方案给出了一个很好的输出

更新我对其进行了轻微修改,以纳入马丁的建议。现在,与使用
isdir
listdir

# prefix components:
space =  '    '
branch = '│   '
# pointers:
tee =    '├── '
last =   '└── '

def stringpath(path):
    # just a helper to get string of PosixPath
    return str(path)

from pathlib import Path
from stat import S_ISDIR
def tree_sftp(sftp, path='.', parent='/', prefix=''):
    """
    Loop through files to print it out
    for file in tree_sftp(sftp):
        print(file)
    """
    fullpath = Path(parent, path)
    strpath = stringpath(fullpath)

    dirs = sftp.listdir_attr(strpath)
    pointers = [tee] * (len(dirs) - 1) + [last]
    pdirs = [Path(fullpath, d.filename) for d in dirs]
    sdirs = [stringpath(path) for path in pdirs]

    for pointer, sd, d in zip(pointers, sdirs, dirs):
        yield prefix + pointer + d.filename
        if S_ISDIR(d.st_mode):
            extension = branch if pointer == tee else space
            yield from tree_sftp(sftp, sd, prefix=prefix + extension)
您可以使用
pysftp

import pysftp
with pysftp.Connection(HOSTNAME, USERNAME, PASSWORD) as sftp:
    for file in tree_sftp(sftp):
        print(file)

让我知道if是否适合您。

依赖
SFTPAttributes
的字符串化行为是一种非常可怕的黑客行为。为什么不正确地使用
stat.S_ISDIR(lstatout.st_模式)
?@PANDAStack-
ftp.lstat(i)
返回类的实例。这个答案的实现方式取决于库如何选择
SFTPAttributes
\uuu repr\uuuu
外观,这是一个完全为程序员调试而设计的界面,可能没有经过测试或保证是恒定的,即使是在补丁版本号之间。基本上,这样做相当于从控制台解析调试输出。它可能会工作,但它非常脆弱,只有在你绝对必须的情况下才应该这样做,并且没有其他选择。在这种情况下,
SFTPAttributes
类的整个要点是方便地封装远程主机上路径的元数据,因此,不只是按照预期的方式使用它显然是愚蠢的。@PANDAStack-
st_mode
是由POSIX定义的。看一看这张照片。此外,。这是代码效率低下。请参阅以获得正确的解决方案。第三件事是,您不应该在SFTP路径上使用Python
Path
class。
路径使用可能与SFTP约定不匹配的本地文件系统约定。尤其是在Windows上,您的代码可能会失败。python
Path
仅用于路径的简单合并。我将其转换为字符串,以便与pysftp一起使用。我只是注意到,我没有包含
stringpath
函数。让我补充一点。它只是一个助手。就是这样,SFTP总是使用前斜杠。而
路径
将使用本地系统路径分隔符。如果这不是正斜杠(就像在Windows上),代码将失败。您正在引入与psftp的
get\r
put\r
相同的问题。看见您可能希望显式使用
PosixPath
# prefix components:
space =  '    '
branch = '│   '
# pointers:
tee =    '├── '
last =   '└── '

def stringpath(path):
    # just a helper to get string of PosixPath
    return str(path)

from pathlib import Path
from stat import S_ISDIR
def tree_sftp(sftp, path='.', parent='/', prefix=''):
    """
    Loop through files to print it out
    for file in tree_sftp(sftp):
        print(file)
    """
    fullpath = Path(parent, path)
    strpath = stringpath(fullpath)

    dirs = sftp.listdir_attr(strpath)
    pointers = [tee] * (len(dirs) - 1) + [last]
    pdirs = [Path(fullpath, d.filename) for d in dirs]
    sdirs = [stringpath(path) for path in pdirs]

    for pointer, sd, d in zip(pointers, sdirs, dirs):
        yield prefix + pointer + d.filename
        if S_ISDIR(d.st_mode):
            extension = branch if pointer == tee else space
            yield from tree_sftp(sftp, sd, prefix=prefix + extension)
import pysftp
with pysftp.Connection(HOSTNAME, USERNAME, PASSWORD) as sftp:
    for file in tree_sftp(sftp):
        print(file)