Вывод Python в Консоль внутри подпроцесса из дочернего скребка

в родительском script, я делаю следующее:

fout=open(outfile,"w")
ferr = open(errfile,"w")

subprocess.call("1.py",stdout=fout,stderr=ferr,shell=True)

В 1.py, script, я хочу, чтобы большая часть сообщения журнала отправлялась в файл журнала, но некоторые сообщения, которые я хочу распечатать на консоли, на основе условий печати:

print "Hello World"

но он печатает в outfile, который я хотел бы распечатать на консоли, я попытался сделать

sys.__stdout__.write("Hello World");

но это тоже не работает. Любая помощь будет оценена!

Ответ 1

Если stdout, stderr перенаправлены, вы можете попробовать распечатать его непосредственно на консоли:

try: # Windows
    from msvcrt import putwch

    def print_to_console(message):
        for c in message:
            putwch(c)
        # newline
        putwch('\r') 
        putwch('\n')
except ImportError: # Unix
    import os

    fd = os.open('/dev/tty', os.O_WRONLY | os.O_NOCTTY)
    tty = os.fdopen(fd, 'w', 1)
    del fd
    def print_to_console(message, *, _file=tty):
        print(message, file=_file)
    del tty

Пример:

print_to_console("Hello TTY!")
# -> Hello TTY!

Ответ 2

Если вы контролируете, что в 1.py, у вас могут быть свои собственные экземпляры stdout и stderr Вы могли бы альтернативно не перенаправлять stdout/stdin in для 1.py, а вместо этого передавать fout/ferr в качестве параметров. что-то вроде:

# assuming python 2.7.x
from __future__ import print_function
import argparse
import sys

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--stdout'
                       , nargs='?'
                       , type=argparse.FileType('a')
                       , default=sys.stdout)
    parser.add_argument( '--stderr'
                       , nargs='?'
                       , type=argparse.FileType('a')
                       , default=sys.stderr)

    namespace = parser.parse_args()

    print("Hello There", file=namespace.stdout)
    print("Error time", file=namespace.stderr)
    print("Always to stdout")
    print("Always to stderr", file=sys.stderr)

И затем запустите его так:

python 1.py --stdout=outfile.log stderr=errfile.log

Для вызова из subprocess:

subprocess.call("1.py",shell=True) # no need to redirect stdout and stderr now