2016-02-12 115 views
2

因此,我正在编写一个命令行工具,并遇到了一个我很好奇的问题。如何检查是否通过ssh远程调用python脚本

该实用程序可以使用文件参数调用,也可以从sys.stdin中读取。本来我是用sys.stdin.isatty()弄清楚,如果数据被管道中,但是,我发现,如果我通过ssh server utility远程调用的效用,sys.stdin.isatty()将返回false,尽管没有实际的数据被输送。

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

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

+0

所有管道都是一样的,所以不要以为你可以。你可能不得不考虑进程组和父进程 - 但这变得非常讨厌 – Soren

回答

3

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

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

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

ssh -t server utility 

不过,我警告你不要做任何的这些。正如你所看到的,试图检测你是否应该接受来自stdin的输入,基于它是否是TTY可能会导致一些令人惊讶的行为。如果他们想要一种方式来在调试某些东西时交互地为程序提供输入,它也可能会导致用户感到沮丧。

添加显式-参数的方法使得它更加明确,并且不太令人惊讶您获得了哪种行为。一些实用程序也只是使用缺少任何文件参数来表示从stdin读取,所以这也是一个不太令人吃惊的选择。

+0

谢谢,这是我正在寻找。看起来我会坚持我的解决方法。 – Laharah

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模块。

+0

这将抛出这些变量的异常没有设置,不返回布尔值。 –

+0

感谢您的回复!我确实可以使用'os.environ ['SSH_TTY']'来判断这个调用是否是一个远程的ssh调用。然而,它无助于分辨这两个调用之间的区别:'ssh server utility'和'echo“data”| ssh服务器工具' – Laharah

+0

谢谢@BrianCampbell。我更新了这个例子。 JavaScript领域的时间太长了。 –

相关问题