gyi*_*yim 8 python ssh subprocess
我正在编写一个使用SSH命令的GUI.我尝试使用子进程模块来调用ssh并设置SSH_ASKPASS环境变量,以便我的应用程序可以弹出一个窗口,询问SSH密码.但是我无法使用给定的SSH_ASKPASS命令使ssh读取密码:它总是在终端窗口中提示它,无论我如何设置DISPLAY,SSH_ASKPASS,TERM环境变量或如何管道标准输入/输出.如何确保ssh与当前TTY分离并使用给定程序读取密码?
我的测试代码是:
#!/usr/bin/env python
import os
import subprocess
env = dict(os.environ)
env['DISPLAY'] = ':9999' # Fake value (trying in OS X and Windows)
del env['TERM']
env['SSH_ASKPASS'] = '/opt/local/libexec/git-core/git-gui--askpass'
p = subprocess.Popen(['ssh', '-T', '-v', 'user@myhost.com'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env
)
p.communicate()
Run Code Online (Sandbox Code Playgroud)
gyi*_*yim 15
SSH仅在进程与TTY分离时才使用SSH_ASKPASS变量(stdin重定向和设置环境变量是不够的).要从控制台分离进程,它应该fork并调用os.setsid().所以我发现的第一个解决方案是:
# Detach process
pid = os.fork()
if pid == 0:
# Ensure that process is detached from TTY
os.setsid()
# call ssh from here
else:
print "Waiting for ssh (pid %d)" % pid
os.waitpid(pid, 0)
print "Done"
Run Code Online (Sandbox Code Playgroud)
使用子进程模块还有一种优雅的方法:在preexec_fn参数中,我们可以传递在执行外部命令之前在子进程中调用的Python函数.所以问题的解决方案是一个额外的线:
env = {'SSH_ASKPASS':'/path/to/myprog', 'DISPLAY':':9999'}
p = subprocess.Popen(['ssh', '-T', '-v', 'user@myhost.com'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
preexec_fn=os.setsid
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20248 次 |
| 最近记录: |