我之前为一个Linux环境编写了一个程序,可以自动以用户身份运行SSHFS二进制文件,并输入存储的ssh私钥密码(公钥已在远程服务器上)。我使用简单的pexpect命令在一台服务器上实现了该功能。 (Ubuntu服务器14.04,ssh版本6.6,sshfs版本2.5)但是,当应用程序移动到Redhat机器(RHEL6.5,ssh版本5.3,sshfs版本2.4)时,该程序的这个单独部分成为了问题。这个简单步骤让我疯狂了一整天,所以我现在转向这个社区寻求支持。 我原本的代码(简化版)如下:
proc = pexpect.spawn('sshfs %s@%s:%s...') #many options, unrelated
proc.expect([pexpect.EOF, 'Enter passphrase for key.*', pexpect.TIMEOUT], timeout=30)
if proc.match_index == 1:
proc.sendline('thepassphrase')
这段代码在ubuntu上可以正常运行,但在rhel上却无法正常工作。我已经尝试了将其传输到子进程的回退方法,但也没有取得太大的成功。
proc = subprocess.Popen('sshfs %s@%s:%s...', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.stdin.write('thepassphrase'+'\n')
proc.stdin.flush()
当然,我已经尝试了许多微小的变化,但都没有成功,当我手动运行该命令时,命令可以正常运行。
更新3/3: 今天我也手动编译并安装了ssh 6.6在RHEL中,以查看是否导致了问题,但即使使用新的ssh二进制文件,问题仍然存在。
更新3/9: 今天,我找到了一个特定的解决方案,它能够正常工作,但我对其他许多不同的解决方案都不起作用感到不满意,并且我仍在寻找为什么的答案。这是我迄今为止做得最好的:
proc = subprocess.check_call("sudo -H -u %s ssh-keygen -p -P %s -N '' -f %s" % (user, userKey['passphrase'], userKey['path']), shell=True)
time.sleep(2)
proc = subprocess.Popen(cmd, shell=True)
proc.communicate()
time.sleep(1)
proc = subprocess.check_call("sudo -H -u %s ssh-keygen -p -P '' -N %s -f %s" % (user, userKey['passphrase'], userKey['path']), shell=True)
移除密钥的密码,挂载驱动器,再重新添加密钥。显然我不喜欢这个解决方案,但在我找到问题根源之前,它将不得不使用。
更新3/23:
由于我的愚蠢,直到现在我才看到这种方法的直接问题,现在我又回到了起点。虽然这个解决方法可以在第一次建立连接时工作,但“-o reconnect”显然会失败,因为sshfs不知道重新连接的密钥。这意味着这个解决方案不再可行,如果有人知道如何让pexpect版本工作,我会非常感激。
ssh-agent
不可行的原因是什么? - twalberg