【问题标题】:"Pseudo-terminal will not be allocated because stdin is not a terminal" when running ssh through python without paramiko在没有 paramiko 的情况下通过 python 运行 ssh 时,“不会分配伪终端,因为 stdin 不是终端”
【发布时间】:2011-06-07 12:46:58
【问题描述】:

我在 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 命令?

【问题讨论】:

标签: python ssh terminal stdin


【解决方案1】:

我是否可以恭敬地建议您问的是错误的问题,正确的问题可能是“我如何确保子进程在我的 python 程序终止时终止”

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

【讨论】:

  • 当我杀死我的 python 脚本时,ssh 子进程确实终止了。但是,除非我将 -t 标志传递给 ssh 命令,否则它在远程主机上启动的命令不会终止。但是当我将 -t 标志传递给 ssh 时,它不尊重该标志并给我粘贴在问题正文中的错误消息。
  • 那么这是我认为您应该查看的另一个进程。为什么当远程 ssh 被丢弃时它没有正确退出。听起来它忽略了一个不应该的信号。跨度>
【解决方案2】:

要在 python 脚本被终止时终止远程命令,您可以(作为ssh-t 选项的替代方法)实施一种解决方法,在标准输入时使用命名管道将“EOF 转换为 SIGHUP”的sshd 正在关闭(请参阅Bug 396 - sshd orphans processes when no pty allocated)。

# sample code in Bash

# press ctrl-d for EOF
ssh localhost '
TUBE=/tmp/myfifo.fifo
rm -f "$TUBE"
mkfifo "$TUBE"
#exec 3<>"$TUBE"

<"$TUBE" sleep 100 &  appPID=$!

# cf. "OpenSSH and non-blocking mode", 
# http://lists.mindrot.org/pipermail/openssh-unix-dev/2005-July/023090.html
#cat >"$TUBE"
#socat -u STDIN "PIPE:$TUBE"
dd of="$TUBE" bs=1 2>/dev/null
#while IFS="" read -r -n 1 char; do printf '%s' "$char"; done > "$TUBE"

#kill -HUP -$appPID 
kill $appPID

rm -f "$TUBE"
'

【讨论】:

    【解决方案3】:

    听起来你真的要求与旧的 nohup 命令相反;也就是说,当底层连接关闭时,确保远程命令响应由 TTY(PTY 或 psuedo-tty)驱动程序生成的 HUP(挂断)信号的某种方式。

    我个人怀疑Paramiko 会比尝试使用 subprocess 模块管理它要好得多。您可以让 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 这是您发布 Best way to run remote commands thru ssh in Twisted? 前一周的一个 SO 线程,但这根本没有涵盖与 pty 相关的问题。查看twisted.conch.ssh.session 的文档表明它具有pty 支持;但将其列为“未记录”。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-30
      • 2019-08-13
      • 2018-07-16
      • 2014-03-10
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      相关资源
      最近更新 更多