Stackoverflow新手,首先,你好。
我正在为我的学校开展一个小项目,这个项目应该是一个自定义的gui(用python编写,因为我从来没有使用python,因为我从未使用过python)是开源的Unison程序。我们试图允许学生和教职员在家里和学校同步一个文件夹,只需尽可能少的输入启动这个程序(如果你愿意的话,这是傻瓜式的)。界面应该只是他们的学校用户名和密码,而gui包装器应该只是将用户名和密码发送给Unison并同步它们。
问题是Unison依次启动SSh并提示输入密码,但是python subprocess.communicate(输入)方法不会让ssh接受密码。我意识到ssh只接受来自终端的输入,我无法弄清楚如何欺骗它。我已经阅读了一些关于使用伪终端的东西,但我仍然难过。 RSA密钥是理想的解决方案,但生成它们然后将它们放在远程服务器上仍然需要我至少使用密码登录一次,这需要上面的解决方案,或者不需要白痴的终端。
def startSync(self):
'''
'''
userName = self.userNameIn.get()
userPass = self.userPassIn.get()
localDir = "/Users/localuser/syncFolder/"
remoteDir = " ssh://schoolServer/remotesyncFolder" #for testing purposes, I set this to my own home machine which logs into my own account if I don't provide me@myserver.net
unisonExecRemotePath = " -servercmd /Users/RemoteMe/unison" #unison is the unix executable responsible for launching unison on the remote system
silenceCmdPrompts = " -silent" #keeps unison from displaying directory differences and asking if its okay to sync
executionString = "./unison" + localDir + remoteDir + unisonExecRemotePath + silenceCmdPrompts
mainProcess = subprocess.Popen(executionString,shell = True, stdin = subprocess.PIPE)
mainProcess.communicate(userPass)
如果我粘贴它,执行字符串在终端中工作正常。如果你这么倾向,任何一般的python技巧也会受到赞赏。
谢谢!
Unison用户手册:http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html
编辑:我还应该注意到,当我正在开发OSX和Linux时,我最终必须使这个窗口兼容,因为我学校的大多数学生都将Windows作为主要(或唯一)机器运行。
答案 0 :(得分:3)
查看pexpect。
import pexpect
child = pexpect.spawn('ssh myname@host.example.com')
child.expect('Password:')
child.sendline(mypassword)
child.interact()
答案 1 :(得分:2)
如果您要向ssh
发送密码,则需要打开伪终端(pty
)并使用该密码与之通话,而不是仅使用stdin
/ stdout
。看看pexpect模块,它就是为了做到这一点。
替代解决方案将涉及用于分发公钥的某种带外机制:例如,设置一个简单的Web应用程序,人们可以粘贴公钥并让它管理authorized_keys
文件代表用户。