“在没有paramiko的情况下通过python运行ssh时,不会分配伪终端,因为stdin不是终端”

时间:2011-01-11 23:51:55

标签: python ssh terminal stdin

我在Python中运行ssh而不使用像Paramiko这样的外部库。我有理由这样做,而不是通过外部库。

基本上我正在做subprocess.Popen("ssh -t bla -- command")

执行此操作时,我收到以下消息:

Pseudo-terminal will not be allocated because stdin is not a terminal.

我使用-t运行它的原因是我希望在我杀死我的python脚本时终止远程命令。

当我尝试-t -t(强迫它)时,我收到以下消息:

tcgetattr: Inappropriate ioctl for device

有没有办法可以通过Python运行带-t的ssh命令?

3 个答案:

答案 0 :(得分:2)

我可以恭敬地建议您提出错误的问题,并且正确的问题可能类似于“当我的python程序终止时如何确保子进程终止”

你可以做一些聪明的unix东西,比如分配一个pty,并确保你的子进程使用它作为std in out等,这样ssh命令认为​​它正在与终端而不是管道通话,但这可能是不是你真正想做的事。

答案 1 :(得分:1)

要在python脚本被终止时终止远程命令,您可以(作为-t的{​​{1}}选项的替代方法)实现使用命名管道将“EOF”转换为SIGHUP的变通方法“当关闭ssh的标准时(见Bug 396 - sshd orphans processes when no pty allocated)。

sshd

答案 2 :(得分:0)

听起来你真的要求旧 nohup 命令的反转;也就是说,某些方法可以确保远程命令响应TTY(PTY或伪相 - tty)驱动程序在与其关联的基础连接时生成的HUP(挂起)信号。

我个人怀疑Paramiko比使用子流程模块管理它要好得多。你可以让Paramiko打开连接,分配pty并执行你的命令而不会有任何瑕疵;并且使用现有 known_hosts 和身份文件(私钥)的代码相对简单。

ActiveState中的此配方Copy files over SSH using paramiko 显示了使用身份文件加载ssh known_hosts以及与您可能正在运行的任何 ssh代理交互的基础知识。从那里你要求的只是一个问题:

您还可以使用SSH协议的TwistedConch实现。但是,围绕Twisted编程框架缠绕可能会更加困难。

以下是Twisted中一个简单的ssh服务器示例,其中包含pty支持:Twisted Conch in 60 Seconds: PTY Requests 这是你的帖子发布前一周的一个SO帖子Best way to run remote commands thru ssh in Twisted?,但这根本不涉及pty相关问题。查看twisted.conch.ssh.session的文档表明它有一些支持;但将其列为“未记载的。”

当然,您甚至可以使用Pexpect,将shell生成到本地 ssh 客户端,然后通过它发送远程命令。这将最接近地模拟从您自己的shell运行命令的方式。