【问题标题】:how to check if python script is being called remotely via ssh如何检查是否通过 ssh 远程调用 python 脚本
【发布时间】:2016-05-23 00:45:05
【问题描述】:

所以我正在编写一个命令行实用程序,但遇到了一个我很好奇的问题。

该实用程序可以使用文件参数调用,也可以从sys.stdin 读取。最初我使用sys.stdin.isatty() 来确定是否正在通过管道输入数据,但是,我发现如果我通过ssh server utility 远程调用该实用程序,sys.stdin.isatty() 将返回 false,尽管事实上没有实际数据正在用管道输入。

作为一种解决方法,我使用- 作为文件参数来强制从标准输入读取(例如:echo "data_here" | utility -f -),但我很想知道是否有可靠的方法来区分管道获取来自进程和管道的数据,因为调用是通过 ssh 才打开的。

系统编程不是我的强项,所以我很感谢你们能提供任何帮助。

【问题讨论】:

  • 所有管道都是一样的,所以不要以为你可以。您可能需要查看进程组和父进程——但这变得非常讨厌

标签: python linux ssh system


【解决方案1】:

您可以通过检查您的环境来判断您是否通过 SSH 被调用。如果您通过 SSH 连接被调用,则将设置环境变量 SSH_CONNECTIONSSH_CLIENT。您可以测试它们是否设置为:

if "SSH_CONNECTION" in os.environ:
    # do something

如果您只想坚持原来的 sys.stdin.isatty() 方法,另一种选择是为 SSH 连接分配一个伪 tty。通常,如果您只是 SSH 进行交互式会话,则 SSH 默认会执行此操作,但如果您提供命令则不会。但是,您可以在提供命令时通过传递 -t 标志强制它这样做:

ssh -t server utility

但是,我会提醒您不要这样做。如您所见,尝试根据是否为 ​​TTY 来检测您是否应该接受来自 stdin 的输入可能会导致一些令人惊讶的行为。如果用户想要在调试某些东西时以交互方式向您的程序提供输入,这也可能会导致用户感到沮丧。

添加显式- 参数的方法使您获得的行为更加明确且不那么令人惊讶。一些实用程序也只是使用缺少任何文件参数来表示从标准输入读取,因此这也是一个不那么令人惊讶的替代方案。

【讨论】:

  • 谢谢,这就是我要找的。看起来我会坚持我的解决方法。
【解决方案2】:

根据this answer 应声明SSH_CLIENTSSH_TTY 环境变量。由此,以下代码应该可以工作:

import os

def running_ssh():
    return 'SSH_CLIENT' in os.environ or 'SSH_TTY' in os.environ

一个更完整的示例将检查父进程以检查它们中的任何一个是否为sshd,这可能需要psutil 模块。

【讨论】:

  • 这会抛出一个异常,这些变量没有设置,不返回布尔值。
  • 感谢您的回复!我确实可以使用os.environ['SSH_TTY'] 来判断呼叫是否是远程 ssh 呼叫。但是,这无助于区分这两个调用:ssh server utilityecho "data" | ssh server utility
  • 谢谢@BrianCampbell。我已经更新了这个例子。在 JavaScript 领域的时间太长了。
猜你喜欢
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
  • 2017-08-02
  • 2018-09-09
相关资源
最近更新 更多