如何检查是否通过ssh远程调用python脚本

时间:2016-02-12 00:48:59

标签: python linux ssh system

所以我正在编写一个命令行工具,而且我遇到了一个我很好奇的问题。

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

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

系统编程不是我的强项,所以我很感激能从你们那里得到任何帮助。

2 个答案:

答案 0 :(得分:3)

您可以通过检查环境来判断是否通过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

但是,我会提醒您不要做其中任何一项。正如您所看到的,尝试检测是否应该接受来自stdin的输入,基于它是否是TTY可能会导致一些令人惊讶的行为。如果用户想要在调试时以交互方式为程序提供输入,也可能会引起用户的沮丧。

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

答案 1 :(得分: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模块。