在 Python 脚本中检查交互式 shell
Posted
技术标签:
【中文标题】在 Python 脚本中检查交互式 shell【英文标题】:Checking for interactive shell in a Python script 【发布时间】:2011-08-31 18:54:51 【问题描述】:我需要确定调用我的 Python 脚本的 shell 是否处于交互模式。如果它处于交互模式,程序应该通过管道输出到 less(1) 以便于阅读。如果没有,它应该简单地将其输出打印到标准输出,以便将其通过管道传送到打印机、文件或不同的寻呼机。
在 shell 脚本中,我会检查提示变量 $PS1 是否已定义,或者在 $- 变量中存储的标志中查找 -i 选项。
在 Python 中测试交互性的首选方法是什么?
【问题讨论】:
【参考方案1】:这通常效果很好
import os, sys
if os.isatty(sys.stdout.fileno()):
...
【讨论】:
sys.stdout.isatty()
更短。
和sys.__stdin__.isatty()
更可靠。 (不受stdin
重定向的影响并允许输出)
@Evpok:OP 要求 stdout,stdin 完全不相关。为了确定是否要分页 output,stdin 确实是要检查的错误流,因为用户可以将某些内容通过管道传输到程序中(因此重定向 stdin 并将其与 tty 断开连接)并且仍然想在寻呼机中查看输出(因为 stdout 没有被重定向)。
@Evpok,你是说sys.__stdout__.isatty()
。当输入不是时,输出可能是 tty,并且 OP 似乎对输出感兴趣
@lunaryom 是的,我知道。但他确实写了“如果它处于交互模式,程序应该通过管道输出到 less(1) 以便于阅读”对我来说这意味着他检查stdin
并根据它的性质重定向stdout
。跨度>
【参考方案2】:
从this link,您可以使用相同的方式并测试标准输入是否与终止(tty)相关联,您可以使用os.isatty() 执行此操作,例如:
>>> os.isatty(0)
True
注意:当您通过 ssh 远程调用命令时,从同一个链接这将失败,给出的解决方案是测试标准输入是否与管道相关联。
【讨论】:
我更喜欢更明显的sys.__stdin__.isatty()
@Evpok:是的,同意,我忘记了文件对象方法 isatty(),谢谢 :)
这似乎等同于 gnibbler 的回答,只是读者必须知道足够多的 unix 才能知道文件 0 是标准输入。在标准输入或标准输出上检查 isatty() 有区别吗?
@jforberg:是的,同意,我认为最好的是@Evpok 评论,sys.__stdin__.isatty()
,AFAIK 交互模式意味着标准输入与终端相关联而不是标准输出,如果我错了,请纠正我: )
是的,Evpok 的解决方案在我看来是最优雅和可读的。谢谢!【参考方案3】:
如果您已经依赖于 matplotlib,或者您不介意引入一个,您可以随时致电 matplotlib.is_interactive()
【讨论】:
查看 github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/… 的第 1049 行。 is_interactive() 只是读取 matplotlib 中的一个全局变量。我看不出它会引用父 shell 的交互性。【参考方案4】:if sys.flags.interactive:
#interactive
else:
#not interactive
http://docs.python.org/library/sys.html#sys.flags
【讨论】:
只有在 Python 使用 -i 选项启动时才会产生 true。使用 -i 选项启动它会在脚本运行后将 Python 置于解释器模式。 sys.flags.interactive 不能用来判断当前shell环境的性质。【参考方案5】:我为测试制作了一个封面类。
例如你有:
class SuperInteractiveClass(object):
def get_data_from_stdin(self):
'... a lot of code here ...'
'... and a lot of other function'
我做了第二节课,只是为了测试
class TestSuperInteractiveClass(SuperInteractiveClass):
prepared_data = []
def add_prepared_data(self,data):
self.prepared_data.append(data)
def get_data_from_stdin(self):
return self.prepared_data.pop(0)
【讨论】:
我不明白。这有什么意义?这如何检查调用者的交互性? 它没有,至少在我能理解的任何方面都没有。看来他已经实现了一个堆栈。以上是关于在 Python 脚本中检查交互式 shell的主要内容,如果未能解决你的问题,请参考以下文章