我正在使用Paramiko和sftp.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
是正确的路径)并且建立了远程路径。
关于类似问题的讨论here和here,但那里提到的任何一点都没有帮助我。我的服务器支持df -hi
命令。
有没有人对此或任何可能的解决方案有任何建议?
修改
根据以下建议,我尝试使用sftp.chdir(remoteDirectory)
更改工作目录,但此调用产生了与上述完全相同的错误。所以这似乎不仅仅是一个上传问题。有什么想法吗?
答案 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开始)