Проверка интерактивной оболочки в скрипте Python

Мне нужно определить, была ли оболочка, вызвавшая мой скрипт Python, в интерактивном режиме или нет. Если бы он был в интерактивном режиме, программа должна направить вывод в less (1) для облегчения чтения. В противном случае он должен просто распечатать свой вывод в stdout, чтобы его можно было направить на принтер, в файл или другой пейджер.

В сценарии оболочки я бы проверил, определена ли переменная подсказки $ PS1, или поискал параметр -i среди флагов, хранящихся в переменной $ -.

Какой метод тестирования интерактивности из Python является предпочтительным?


person jforberg    schedule 24.05.2011    source источник


Ответы (5)


Часто это работает достаточно хорошо

import os, sys
if os.isatty(sys.stdout.fileno()):
    ...
person John La Rooy    schedule 24.05.2011
comment
sys.stdout.isatty() короче. - person lunaryorn; 24.05.2011
comment
И sys.__stdin__.isatty() надежнее. (не зависит от stdin перенаправления и позволяет выводить по конвейеру) - person Evpok; 24.05.2011
comment
@Evpok: OP запросил stdout, stdin совершенно не связан. Чтобы узнать, выводить ли страницу output или нет, stdin - это действительно неправильный поток для проверки, потому что пользователь может передать что-то в программу (таким образом, перенаправить stdin и отключить его от tty) и все же хотите видеть вывод в пейджере (потому что stdout не перенаправляется). - person lunaryorn; 24.05.2011
comment
@Evpok, ты имеешь ввиду sys.__stdout__.isatty(). Возможно, что вывод будет tty, когда ввода нет, и OP, похоже, заинтересован в выводе - person John La Rooy; 24.05.2011
comment
@lunaryom Да, я знаю. Но он написал: «Если это было в интерактивном режиме, программа должна направлять вывод в less (1), для меня это означает, что он проверяет stdin и перенаправляет stdout в соответствии с его характером. - person Evpok; 24.05.2011
comment
@Evpok, @lunaryom Я делаю мужскую (1) -й программу. Я хочу, чтобы он вел себя примерно так, как это делает человек, то есть выводит конвейер на less (1), если он интерактивен, но просто распечатывает его, если нет. Поэтому я, наверное, хочу проверить, является ли stdout терминалом. - person jforberg; 24.05.2011

Из этой ссылки вы можете использовать тот же способ и проверить, связан ли stdin с terminate (tty), это можно сделать с помощью os.isatty () , пример:

>>> os.isatty(0)
True

Примечание: по той же ссылке это не удастся, когда вы вызываете команду удаленно через ssh, решение состоит в том, чтобы проверить, связан ли stdin с каналом.

person mouad    schedule 24.05.2011
comment
Я предпочитаю более очевидное sys.__stdin__.isatty() - person Evpok; 24.05.2011
comment
@Evpok: Да, согласен, я забыл о методе файлового объекта isatty (), спасибо :) - person mouad; 24.05.2011
comment
Это похоже на ответ gnibbler, за исключением того, что читатель должен знать достаточно unix, чтобы знать, что файл 0 является стандартным вводом. Как вы думаете, есть ли разница между проверкой isatty () на stdin или stdout? - person jforberg; 24.05.2011
comment
@jforberg: да, согласен, и я думаю, что лучший из них - это комментарий @Evpok, sys.__stdin__.isatty() и интерактивный режим AFAIK означает, что stdin связан с терминалом, а не с stdout, поправьте меня, если я ошибаюсь :) - person mouad; 24.05.2011
comment
Да, решение Евпока на мой взгляд самое изящное и читаемое. Спасибо! - person jforberg; 24.05.2011

Если у вас уже есть зависимость от matplotlib или вы не против ее ввести, вы всегда можете просто позвонить по matplotlib.is_interactive ()

person schwartrer    schedule 15.12.2012
comment
Посмотрите строку 1049 в github.com/matplotlib/matplotlib/blob. / мастер / lib / matplotlib /. is_interactive () просто читает глобальную переменную в matplotlib. Я не вижу никаких гарантий, что это будет относиться к интерактивности родительской оболочки. - person jforberg; 16.12.2012

if sys.flags.interactive:
    #interactive
else:
    #not interactive 

http://docs.python.org/library/sys.html#sys.flags

person Pych    schedule 29.07.2011
comment
Это приводит к истинному результату только в том случае, если Python был запущен с параметром -i. Запуск его с параметром -i переведет Python в режим интерпретатора после запуска сценария. sys.flags.interactive не может использоваться для определения характера текущего окружения оболочки. - person chiborg; 12.10.2011

Делаю обложку класса для тестирования.

Например, у вас есть:

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)
person Oduvan    schedule 24.05.2011
comment
Я не понимаю. Какой в ​​этом смысл? Как это проверяет интерактивность invoker'а? - person Evpok; 24.05.2011
comment
Это не так, по крайней мере, я не могу понять. Кажется, он реализовал стек. - person jforberg; 24.05.2011