简体   繁体   English

使用Popen的Python中的持久ssh会话

[英]Persistent ssh session in Python using Popen

I am creating a movie controller (Pause/Stop...) using python where I ssh into a remote computer, and issue commands into a named pipe like so 我正在使用python创建一个电影控制器(暂停/停止...),在其中将它SSH到远程计算机,并像这样将命令发布到命名管道中

echo -n q > ~/pipes/pipename

I know this works if I ssh via the terminal and do it myself, so there is no problem with the setup of the named pipe redirection. 我知道如果我通过终端ssh并自己完成此操作,那么命名管道重定向的设置没有问题。 My problem is that setting up an ssh session takes time (1-3 seconds), whereas I want the pause command to be instantaneous. 我的问题是设置ssh会话需要花费时间(1-3秒),而我希望暂停命令是瞬时的。 Therefore, I thought of setting up a persistent pipe like so: 因此,我想到了建立像这样的持久管道:

controller = subprocess.Popen ( "ssh -T -x <hostname>", shell = True, close_fds = True, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE )

Then issue commands to it like so 然后像这样发出命令

controller.stdin.write ( 'echo -n q > ~/pipes/pipename' )

I think the problem is that ssh is interactive so it expects a carriage return. 我认为问题在于ssh是交互式的,因此它期望回车。 This is where my problems begin, as nearly everyone who has asked this question has been told to use an existing module: 这是我的问题开始的地方,因为几乎所有询问此问题的人都被告知要使用现有模块:

Which is fine, but I am so close. 很好,但是我很亲近。 I just need to know how to include the carriage return, otherwise, I have to go learn all these other modules, which mind you is not trivial (for example, right now I can't figure out how pexpect uses either my /etc/hosts file or my ssh keyless authentications). 我只需要知道如何包含回车符,否则,我必须去学习所有其他模块,以为您不容易(例如,现在我不知道pexpect如何使用我的/etc/hosts文件或我的ssh无密钥身份验证)。

I'm not sure why it's not working the way you have it set up, but I'll take a stab at this. 我不确定为什么它无法按您设置的方式工作,但我会对此采取行动。 I think what I would do is change the Popen call to: 我认为我要做的就是将Popen调用更改为:

controller = subprocess.Popen("ssh -T -x <hostname> \"sh -c 'cat > ~/pipes/pipename'\"", ...

And then simply controller.stdin.write('q') . 然后只需controller.stdin.write('q')

To add a newline to the command, you will need to add a newline to the string: 要在命令中添加换行符,您需要在字符串中添加换行符:

controller.stdin.write('\n')

You may also need to flush the pipe: 您可能还需要冲洗管道:

controller.stdin.flush()

And of course the controller has to be ready to receive new data, or you could block forever trying to send it data. 当然,控制器必须准备好接收新数据,否则您将永远无法尝试发送数据。 (And if the reason it's not ready is that it's blocking forever waiting for you to read from its stdout, which is possible on some platforms, you're deadlocked unrecoverably.) (如果它还没有准备好的原因是它永远阻止您从其标准输出中读取信息(在某些平台上可能会发生这种情况,那么您将陷入无法恢复的僵局)。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM