IOError: [Errno 2] 没有该文件 - Paramiko put()

10 投票
6 回答
35427 浏览
提问于 2025-04-17 19:31

我正在通过 SFTP 上传一个文件,使用的是 Paramiko 库,具体方法是 sftp.put(localFile, remoteFile)。如果需要的话,我会先创建必要的目录,代码如下:

    makeCommand = 'mkdir -p "' + remotePath + '"'
    ssh.exec_command(makeCommand)

这个方法有时候能成功,但我偶尔会遇到以下错误:

    sftp.put(localFile, remoteFile)
    File "build/bdist.macosx-10.8-intel/egg/paramiko/sftp_client.py", line 565, in put
    File "build/bdist.macosx-10.8-intel/egg/paramiko/sftp_client.py", line 245, in open
    File "build/bdist.macosx-10.8-intel/egg/paramiko/sftp_client.py", line 635, in _request
    File "build/bdist.macosx-10.8-intel/egg/paramiko/sftp_client.py", line 682, in _read_response
    File "build/bdist.macosx-10.8-intel/egg/paramiko/sftp_client.py", line 708, in _convert_status
    IOError: [Errno 2] No such file 

尽管本地文件确实存在(而且 localFile 是正确的路径),远程路径也已经创建好了。关于这个问题,有一些讨论可以在 这里这里 找到,但那些讨论中的建议对我没有帮助。我的服务器支持 df -hi 命令。有没有人能给我一些建议或者可能的解决方案?

编辑

根据下面的建议,我尝试用 sftp.chdir(remoteDirectory) 来更改工作目录,但这个调用产生的错误和之前的一模一样。所以看起来这不仅仅是上传的问题。还有什么想法吗?

6 个回答

2

你确定这个目录已经创建好,并且是你远程工作的目录吗?Paramiko有自己的一些方法可以用来创建新目录和浏览远程文件系统。你可以考虑使用类似下面的代码:

sftp.mkdir(remotedirectory)
sftp.chdir(remotedirectory)
sftp.put(localfile, remotefile)
17

put方法有一个叫做confirm的参数,默认是开启的,这个参数会在文件传输后检查一下文件的状态。

在我的情况下,我传输文件的远程服务器会立即把任何传输过来的文件移动到另一个地方去处理,这导致状态检查失败。把confirm参数设置为False就解决了这个问题。

def put(self, localpath, remotepath, callback=None, confirm=True):

来自paramiko源代码的sftp_client.py:

:param bool confirm: 是否在之后对文件进行stat()检查,以确认文件 大小(自1.7.7版本起)

13

看起来这是一个远程文件夹权限的问题。虽然在上传文件之前已经创建了远程文件夹,但似乎文件夹的权限阻止了文件的上传。

这个问题和这个问题有关——如果我在上传之前就把要上传的文件夹的权限设置为开放,那么程序就可以顺利上传了。虽然通常遇到权限问题时,我应该会看到IOError: [Errno 13] Permission denied的错误,但自从我做了这些更改后,就没有遇到任何错误。

我不确定是服务器给Paramiko的响应出了问题,还是Paramiko本身的bug导致出现IOError: [Errno 2] No such file的错误,而不是Errno 13,但看起来这个问题已经解决了。

撰写回答