스크립팅을 사용하여 stdout을 파일과 콘솔 모두로 리디렉션하는 방법은 무엇입니까?
파이썬 스크립트를 실행하고 텍스트 파일의 출력을 캡처하고 콘솔에 표시하고 싶습니다.
파이썬 스크립트 자체의 속성으로 지정하고 싶습니다. echo "hello world" | tee test.txt
매번 명령 프롬프트에서 명령 을 사용하지 마십시오 .
스크립트 내에서 시도했습니다.
sys.stdout = open('log.txt','w')
그러나 이것은 화면에 stdout 출력을 표시하지 않습니다.
로깅 모듈에 대해 들었지만 해당 모듈을 사용하여 작업을 수행하는 데 운이 없었습니다.
Python 파일을 실행하는 동안 셸 리디렉션을 사용할 수 있습니다.
python foo_bar.py > file
이것은 파이썬 소스에서 stdout에 인쇄되는 모든 결과를 로그 파일에 파일로 기록합니다.
또는 스크립트 내에서 로깅을 원하는 경우 :
import sys
class Logger(object):
def __init__(self):
self.terminal = sys.stdout
self.log = open("logfile.log", "a")
def write(self, message):
self.terminal.write(message)
self.log.write(message)
def flush(self):
#this flush method is needed for python 3 compatibility.
#this handles the flush command by doing nothing.
#you might want to specify some extra behavior here.
pass
sys.stdout = Logger()
이제 다음을 사용할 수 있습니다.
print "Hello"
이것은 stdout과 logfile 모두에 "Hello"를 기록합니다.
출력을 콘솔과 텍스트 파일로 동시에 리디렉션하는 방법이 있습니다.
te = open('log.txt','w') # File where you need to keep the logs
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
te.write(data) # Write the data of stdout here to a text file as well
sys.stdout=Unbuffered(sys.stdout)
로깅 모듈을 사용하여 앱 디버그 및 팔로우
다음은 파일 및 콘솔 / stdout에 로그인하는 방법입니다.
import logging
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='logs_file',
filemode='w')
# Until here logs only to file: 'logs_file'
# define a new Handler to log to console as well
console = logging.StreamHandler()
# optional, set the logging level
console.setLevel(logging.INFO)
# set a format which is the same for console use
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)
# Now, we can log to both ti file and console
logging.info('Jackdaws love my big sphinx of quartz.')
logging.info('Hello world')
출처 : https://docs.python.org/2/howto/logging-cookbook.html
더 쉬운 해결책을 고안했습니다. 파일이나 화면 또는 둘 다에 인쇄 할 함수를 정의하기 만하면됩니다. 아래 예에서는 사용자가 출력 파일 이름을 인수로 입력하도록 허용하지만 필수는 아닙니다.
OutputFile= args.Output_File
OF = open(OutputFile, 'w')
def printing(text):
print text
if args.Output_File:
OF.write(text + "\n")
그런 다음 파일 및 / 또는 화면 모두에 행을 인쇄하는 데 필요한 것은 printing (Line_to_be_printed)입니다.
Amith Koujalgi의 답변을 기반으로 로깅에 사용할 수있는 간단한 모듈은 다음과 같습니다.
transcript.py :
"""
Transcript - direct print output to a file, in addition to terminal.
Usage:
import transcript
transcript.start('logfile.log')
print("inside file")
transcript.stop()
print("outside file")
"""
import sys
class Transcript(object):
def __init__(self, filename):
self.terminal = sys.stdout
self.logfile = open(filename, "a")
def write(self, message):
self.terminal.write(message)
self.logfile.write(message)
def flush(self):
# this flush method is needed for python 3 compatibility.
# this handles the flush command by doing nothing.
# you might want to specify some extra behavior here.
pass
def start(filename):
"""Start transcript, appending print output to given filename"""
sys.stdout = Transcript(filename)
def stop():
"""Stop transcript and return print functionality to normal"""
sys.stdout.logfile.close()
sys.stdout = sys.stdout.terminal
from IPython.utils.io import Tee
from contextlib import closing
print('This is not in the output file.')
with closing(Tee("outputfile.log", "w", channel="stdout")) as outputstream:
print('This is written to the output file and the console.')
# raise Exception('The file "outputfile.log" is closed anyway.')
print('This is not written to the output file.')
# Output on console:
# This is not in the output file.
# This is written to the output file and the console.
# This is not written to the output file.
# Content of file outputfile.txt:
# This is written to the output file and the console.
의 Tee
클래스는 IPython.utils.io
원하는 것을 수행하지만-문 에서 호출하는 데 필요한 __enter__
및 __exit__
메서드가 with
없습니다. 그것들은 contextlib.closing
.
Python 스크립트가 외부에서 사용되는 방식을 수정하지 않고 출력을 파일 및 터미널로 리디렉션하려면 다음을 사용할 수 있습니다 pty.spawn(itself)
.
#!/usr/bin/env python
"""Redirect stdout to a file and a terminal inside a script."""
import os
import pty
import sys
def main():
print('put your code here')
if __name__=="__main__":
sentinel_option = '--dont-spawn'
if sentinel_option not in sys.argv:
# run itself copying output to the log file
with open('script.log', 'wb') as log_file:
def read(fd):
data = os.read(fd, 1024)
log_file.write(data)
return data
argv = [sys.executable] + sys.argv + [sentinel_option]
rc = pty.spawn(argv, read)
else:
sys.argv.remove(sentinel_option)
rc = main()
sys.exit(rc)
경우 pty
모듈 (Windows에서) 사용할 수 없습니다 당신은 그것을 대체 할 수있는 teed_call()
기능을 더 휴대용이지만 일반 파이프 대신 의사 터미널을 제공합니다 - 그것은 일부 프로그램의 동작을 변경할 수 있습니다.
파일 류 객체로 대체 하는 것보다 pty.spawn
및 subprocess.Popen
기반 솔루션 의 장점은 sys.stdout
예를 들어 스크립트가 stdout / stderr에서 출력을 생성 할 수있는 다른 프로세스를 시작하는 경우 파일 설명자 수준에서 출력을 캡처 할 수 있다는 것입니다. 관련 질문에 대한 내 대답을 참조하십시오 : stdout을 Python의 파일로 리디렉션합니까?
다음은 콘솔에 인쇄하고 동일한 출력을 파일에 쓰는 간단한 컨텍스트 관리자입니다. 또한 파일에 모든 예외를 기록합니다.
import traceback
import sys
# Context manager that copies stdout and any exceptions to a log file
class Tee(object):
def __init__(self, filename):
self.file = open(filename, 'w')
self.stdout = sys.stdout
def __enter__(self):
sys.stdout = self
def __exit__(self, exc_type, exc_value, tb):
sys.stdout = self.stdout
if exc_type is not None:
self.file.write(traceback.format_exc())
self.file.close()
def write(self, data):
self.file.write(data)
self.stdout.write(data)
def flush(self):
self.file.flush()
self.stdout.flush()
컨텍스트 관리자를 사용하려면 :
print("Print")
with Tee('test.txt'):
print("Print+Write")
raise Exception("Test")
print("Print")
여기에서 몇 가지 솔루션을 시도했지만 파일과 콘솔에 동시에 쓰는 솔루션을 찾지 못했습니다. 그래서 여기에 내가 한 일이 있습니다 (이 답변을 바탕으로)
class Logger(object):
def __init__(self):
self.terminal = sys.stdout
def write(self, message):
with open ("logfile.log", "a", encoding = 'utf-8') as self.log:
self.log.write(message)
self.terminal.write(message)
def flush(self):
#this flush method is needed for python 3 compatibility.
#this handles the flush command by doing nothing.
#you might want to specify some extra behavior here.
pass
sys.stdout = Logger()
This solution uses more computing power, but reliably saves all of the data from stdout into logger file and uses less memeory. For my needs I've added time stamp into self.log.write(message) aswell. Works great.
I tried this:
"""
Transcript - direct print output to a file, in addition to terminal.
Usage:
import transcript
transcript.start('logfile.log')
print("inside file")
transcript.stop()
print("outside file")
"""
import sys
class Transcript(object):
def __init__(self, filename):
self.terminal = sys.stdout, sys.stderr
self.logfile = open(filename, "a")
def write(self, message):
self.terminal.write(message)
self.logfile.write(message)
def flush(self):
# this flush method is needed for python 3 compatibility.
# this handles the flush command by doing nothing.
# you might want to specify some extra behavior here.
pass
def start(filename):
"""Start transcript, appending print output to given filename"""
sys.stdout = Transcript(filename)
def stop():
"""Stop transcript and return print functionality to normal"""
sys.stdout.logfile.close()
sys.stdout = sys.stdout.terminal
sys.stderr = sys.stderr.terminal
you can redirect the output to a file by using >> python with print rint's "chevron" syntax as indicated in the docs
let see,
fp=open('test.log','a') # take file object reference
print >> fp , "hello world" #use file object with in print statement.
print >> fp , "every thing will redirect to file "
fp.close() #close the file
checkout the file test.log you will have the data and to print on console just use plain print statement .
'development' 카테고리의 다른 글
버튼을 점프시키는 부트 스트랩 툴팁 (0) | 2020.12.03 |
---|---|
Bash 배열에 요소가 있는지 확인 (0) | 2020.12.03 |
문자열을 BigInteger로 어떻게 변환합니까? (0) | 2020.12.03 |
Swift 3 UnsafePointer ($ 0)는 더 이상 Xcode 8 베타 6에서 컴파일되지 않습니다. (0) | 2020.12.03 |
Visual Studio Build Framework에서 .NET Core 2.2를 선택할 수 없음 (0) | 2020.12.03 |