我需要有一个功能,基本上会模拟用户创建一个端口转发与ssh.所以,基本上应该这样工作:- execute ssh -f -N -L 10000:gateway:11000 localhost
-如果该命令有输出,则显示给用户并将用户的输入作为响应- finish我在下面编写的代码几乎可以满足我的需要:
ssh_proc = Popen(['ssh', '-f', '-N', '-L', '10000:gateway:11000', 'localhost'], stdin=PIPE, stdout=PIPE)
stdoutdata, stderrdata = ssh_proc.communicate()
但问题是它从来没有完成。我看到命令被执行,转发隧道被创建,但communicate()仍然卡住。我可以用Ctrl+C打破它,并得到如下:
^CTraceback (most recent call last):
File "sshman.py", line 278, in <module>
add(args.remote_host, args.remote_port, args.local_port, args.local_host)
File "sshman.py", line 125, in add
stdoutdata, stderrdata = ssh_proc.communicate()
File "/usr/lib64/python2.7/subprocess.py", line 740, in communicate
return self._communicate(input)
File "/usr/lib64/python2.7/subprocess.py", line 1256, in _communicate
stdout, stderr = self._communicate_with_poll(input)
File "/usr/lib64/python2.7/subprocess.py", line 1310, in _communicate_with_poll
ready = poller.poll()
KeyboardInterrupt
因为我在ssh命令中使用了-f,所以它应该分叉连接。有没有方法在完成时中断communicate(),或者有没有更优雅的解决方案?
提前感谢您的任何意见/建议/评论。
2条答案
按热度按时间0yycz8jy1#
我想解决办法很简单
xqk2d5yq2#
我在尝试设置ssh隧道时遇到了一个相关的问题,communicate()将永远挂起,我发现它从stderr和stdout读取,所以如果你的命令没有向stderr写入任何内容,那么它将挂起,因为它正在等待从stderr读取一些内容(fd = 2)。因此,作为一个解决方案,你可以使用os.set_blocking(ssh_proc.stderr.fileno(),False):
这样communicate()函数就不会阻塞进程,即使没有从stdout或stderr读取任何内容。