【问题标题】:Persistent ssh session in Python using Popen使用 Popen 的 Python 中的持久 ssh 会话
【发布时间】:2013-11-06 22:04:53
【问题描述】:

我正在使用 python 创建一个电影控制器(暂停/停止...),我通过 ssh 连接到远程计算机,然后像这样向命名管道发出命令

echo -n q > ~/pipes/pipename

我知道如果我通过终端 ssh 并自己执行此操作,这将有效,因此命名管道重定向的设置没有问题。我的问题是设置 ssh 会话需要时间(1-3 秒),而我希望暂停命令是即时的。因此,我想到了像这样设置一个持久管道:

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

然后像这样向它发出命令

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

我认为问题在于ssh 是交互式的,因此它需要回车。这就是我的问题开始的地方,因为几乎所有提出这个问题的人都被告知要使用现有模块:

这很好,但我很接近。我只需要知道如何包含回车符,否则,我必须去学习所有这些其他模块,这并不重要(例如,现在我无法弄清楚 pexpect 如何使用我的/etc/hosts文件或我的 ssh 无密钥身份验证)。

【问题讨论】:

  • 我假设只是将 '\n' 添加到您的字符串中不起作用?
  • @kyle 不,我试过 \n\r
  • 除了需要添加\n之外,您通常还需要添加stdin.flush()
  • @abarnert 之前、期间或之后 =P
  • @puk:这可能意味着第一个连接(为自己建立 tcp 连接和所有连续相应的 ssh 命令的连接)以这样的方式失败,留下陈旧的ControlPath 文件,你必须手动删除它。保持第一个连接处于活动状态,并在它意外死亡后进行清理。

标签: python ssh


【解决方案1】:

要在命令中添加换行符,您需要在字符串中添加换行符:

controller.stdin.write('\n')

您可能还需要冲洗管道:

controller.stdin.flush()

当然,控制器必须准备好接收新数据,否则您可能会永远阻止尝试向其发送数据。 (如果它没有准备好的原因是它永远阻塞等待你从它的标准输出中读取,这在某些平台上是可能的,那么你就会陷入不可恢复的死锁。)

【讨论】:

    【解决方案2】:

    我不确定为什么它没有按照您设置的方式工作,但我会尝试一下。我想我会做的是将Popen 调用更改为:

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

    然后简单地controller.stdin.write('q')

    【讨论】:

      猜你喜欢
      • 2014-02-22
      • 2010-10-09
      • 2017-02-07
      • 2011-07-11
      • 1970-01-01
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多