【问题标题】:Checking for interactive shell in a Python script在 Python 脚本中检查交互式 shell
【发布时间】:2011-08-31 18:54:51
【问题描述】:

我需要确定调用我的 Python 脚本的 shell 是否处于交互模式。如果它处于交互模式,程序应该通过管道输出到 less(1) 以便于阅读。如果没有,它应该简单地将其输出打印到标准输出,以便将其通过管道传送到打印机、文件或不同的寻呼机。

在 shell 脚本中,我会检查提示变量 $PS1 是否已定义,或者在 $- 变量中存储的标志中查找 -i 选项。

在 Python 中测试交互性的首选方法是什么?

【问题讨论】:

    标签: python shell pipe interactive


    【解决方案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()

    【讨论】:

    【解决方案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)
    

    【讨论】:

    • 我不明白。这有什么意义?这如何检查调用者的交互性?
    • 它没有,至少在我能理解的任何方面都没有。看来他已经实现了一个堆栈。
    猜你喜欢
    • 2016-05-29
    • 2017-02-13
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 2023-04-10
    相关资源
    最近更新 更多