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

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

该实用程序可以用文件参数调用,也可以从sys.stdin读取。 最初我使用sys.stdin.isatty()来判断数据是否在pipe道中,但是,如果我通过ssh server utility程序远程调用实用ssh server utility ,则sys.stdin.isatty()将返回false,尽pipe事实上,没有实际的数据被input。

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

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

你可以通过检查你的环境来判断你是否通过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可能会导致一些令人惊讶的行为。 如果他们想要一种方式来在调试时交互地提供输入到程序中,那么也可能会导致用户感到沮丧。

添加一个明确的参数的方法使得它更明确,并且不太让人惊讶你得到的行为。 一些实用程序也只是使用缺少任何文件参数意味着从标准输入读取,所以这也是一个不太令人吃惊的选择。

根据这个回答 ,应该声明SSH_CLIENTSSH_TTY环境变量。 从这一点,下面的代码应该工作:

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

一个更完整的例子将检查父进程,检查是否有任何sshd这可能需要psutil模块。