IOError:[Errno 2]没有这样的文件 - Paramiko put()

时间:2013-03-18 16:29:07

标签: python python-2.7 sftp paramiko

我正在使用Paramikosftp.put(localFile, remoteFile)通过SFTP上传文件。如果需要,我首先使用

创建必要的目录
    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是正确的路径)并且建立了远程路径。 关于类似问题的讨论herehere,但那里提到的任何一点都没有帮助我。我的服务器支持df -hi命令。 有没有人对此或任何可能的解决方案有任何建议?

修改

根据以下建议,我尝试使用sftp.chdir(remoteDirectory)更改工作目录,但此调用产生了与上述完全相同的错误。所以这似乎不仅仅是一个上传问题。有什么想法吗?

4 个答案:

答案 0 :(得分:6)

这似乎是一个远程文件夹权限问题。虽然远程文件夹是在文件上载之前制作的,但是文件夹上的权限似乎阻止了上传。

问题与this问题有关 - 如果我在上传之前对我要上传的文件夹设置了开放权限,程序可以正常上传。虽然对于权限问题我应该IOError: [Errno 13] Permission denied,因为我做了更改后没有遇到任何错误。

我不确定这是服务器给Paramiko的响应是什么问题,或Paramiko本身的错误导致IOError: [Errno 2] No such file而不是Errno 13,但这似乎有解决了这个问题。

答案 1 :(得分:2)

IOError是本地的,所以(无论出于何种原因)你的本地python似乎找不到localFile。在通话前安全检查可能有助于追踪问题:

if os.path.isfile(localFile):
    sftp.put(localFile, remoteFile)
else:
    raise IOError('Could not find localFile %s !!' % localFile)

如果你肯定localFile确实存在,那么这可能只是一个路径问题 - 在绝对或相对路径上是localFile吗?无论哪种方式,上面的if语句都会捕获它。

修改

跟踪paramiko文件显示sftp_client.py的第245行(抛出异常的那一行)实际上是

fr = self.file(remotepath, 'wb')
由于paramiko为远程文件抛出IOError,这是非常误导的!我现在最好的猜测是remoteFile是缺少目录或您无权访问的目录。

出于兴趣,您可以列出远程目录

sftp.listdir(path=os.path.dirname(remoteFile))

检查它是否在那里(或者它可能在那里,你可以写信给它)?

答案 2 :(得分:2)

您确定目录已创建且它是您的远程工作目录吗? Paramiko有自己的方法来创建新目录和导航远程文件系统。考虑使用类似的东西:

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

答案 3 :(得分:2)

put方法具有一个默认启用的确认参数,该参数将在传输后对文件进行统计。

在我的情况下,我正在将远程服务器传输文件,立即将所有传输的文件移动到另一个位置进行处理,这导致统计信息失败。将确认参数设置为False可以解决此问题。

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

从paramiko来源sftp_client.py:

:param bool确认: 之后是否对文件执行stat()以确认文件 大小(自1.7.7开始)