이 Python 스크립트의 출력을 텍스트 파일에 어떻게 저장할 수 있습니까? 이는 클라이언트가 Windows 또는 Office를 연결하고 정품 인증하는 KMS 서버입니다. 로그를 텍스트 파일로 저장하고 싶습니다. 이 서버는 centos 7을 기반으로 한다는 점을 언급할 가치가 있습니다.
#!/usr/bin/python2.7
import argparse
import binascii
import hashlib
import random
import re
import socket
import SocketServer
import struct
import uuid
import rpcBind, rpcRequest
from dcerpc import MSRPCHeader
from rpcBase import rpcBase
config = {}
def main():
parser = argparse.ArgumentParser()
parser.add_argument("ip", nargs="?", action="store", default="0.0.0.0", help="The IP address to listen on. The default is \"0.0.0.0\" (all interfaces).", type=str)
parser.add_argument("port", nargs="?", action="store", default=1688, help="The network port to listen on. The default is \"1688\".", type=int)
parser.add_argument("-e", "--epid", dest="epid", default=None, help="Use this flag to manually specify an ePID to use. If no ePID is specified, a random ePID will be generated.", type=str)
parser.add_argument("-l", "--lcid", dest="lcid", default=1033, help="Use this flag to manually specify an LCID for use with randomly generated ePIDs. If an ePID is manually specified, this setting is ignored.", type=int)
parser.add_argument("-c", "--client-count", dest="CurrentClientCount", default=26, help="Use this flag to specify the current client count. Default is 26. A number >25 is required to enable activation.", type=int)
parser.add_argument("-a", "--activation-interval", dest="VLActivationInterval", default=120, help="Use this flag to specify the activation interval (in minutes). Default is 120 minutes (2 hours).", type=int)
parser.add_argument("-r", "--renewal-interval", dest="VLRenewalInterval", default=1440 * 7, help="Use this flag to specify the renewal interval (in minutes). Default is 10080 minutes (7 days).", type=int)
parser.add_argument("-v", "--verbose", dest="verbose", action="store_const", const=True, default=False, help="Use this flag to enable verbose output.")
parser.add_argument("-d", "--debug", dest="debug", action="store_const", const=True, default=False, help="Use this flag to enable debug output. Implies \"-v\".")
parser.add_argument("-s", "--sqlite", dest="sqlite", action="store_const", const=True, default=False, help="Use this flag to store request information from unique clients in an SQLite database.")
parser.add_argument("-o", "--log", dest="log", action="store_const", const=True, default=False, help="Use this flag to enable logging to a file.")
parser.add_argument("-w", "--hwid", dest="hwid", action="store", default='364F463A8863D35F', help="Use this flag to specify a HWID. The HWID must be an 16-character string of hex characters. The default is \"364F463A8863D35F\".")
config.update(vars(parser.parse_args()))
# Sanitize HWID
try:
config['hwid'] = binascii.a2b_hex(re.sub(r'[^0-9a-fA-F]', '', config['hwid'].strip('0x')))
if len(binascii.b2a_hex(config['hwid'])) < 16:
print "Error: HWID \"%s\" is invalid. Hex string is too short." % binascii.b2a_hex(config['hwid'])
return
elif len(binascii.b2a_hex(config['hwid'])) > 16:
print "Error: HWID \"%s\" is invalid. Hex string is too long." % binascii.b2a_hex(config['hwid'])
return
except TypeError:
print "Error: HWID \"%s\" is invalid. Odd-length hex string." % binascii.b2a_hex(config['hwid'])
return
if config['debug']:
config['verbose'] = True
try:
import sqlite3
config['dbSupport'] = True
except:
print "Warning: Module \"sqlite3\" is not installed--database support disabled."
config['dbSupport'] = False
server = SocketServer.TCPServer((config['ip'], config['port']), kmsServer)
server.timeout = 5
print "TCP server listening at %s on port %d." % (config['ip'],config['port'])
server.serve_forever()
class kmsServer(SocketServer.BaseRequestHandler):
def setup(self):
self.connection = self.request
print "Connection accepted: %s:%d" % (self.client_address[0],self.client_address[1])
def handle(self):
while True:
# self.request is the TCP socket connected to the client
try:
self.data = self.connection.recv(1024)
except socket.error, e:
if e[0] == 104:
print "Error: Connection reset by peer."
break
else:
raise
if self.data == '' or not self.data:
print "No data received!"
break
# self.data = bytearray(self.data.strip())
# print binascii.b2a_hex(str(self.data))
packetType = MSRPCHeader(self.data)['type']
if packetType == rpcBase.packetType['bindReq']:
if config['verbose']:
print "RPC bind request received."
handler = rpcBind.handler(self.data, config)
elif packetType == rpcBase.packetType['request']:
if config['verbose']:
print "Received activation request."
handler = rpcRequest.handler(self.data, config)
else:
print "Error: Invalid RPC request type", packetType
break
handler.populate()
res = str(handler.getResponse())
self.connection.send(res)
if packetType == rpcBase.packetType['bindReq']:
if config['verbose']:
print "RPC bind acknowledged."
elif packetType == rpcBase.packetType['request']:
if config['verbose']:
print "Responded to activation request."
break
def finish(self):
self.connection.close()
print "Connection closed: %s:%d" % (self.client_address[0],self.client_address[1])
if __name__ == "__main__":
main()
이 유닛 파일을 사용하여 로그를 생성하고 있지만 로그가 생성되지 않습니다.
[Unit]
Description=PY-KMS
[Service]
ExecStart=/usr/local/kms/server.py 192.168.1.10 1688 -v
StandardOutput=/usr/local/kms/kms.log
StandardError=/usr/local/kms/kms-error.log
[Install]
WantedBy=multi-user.target
답변1
출력 리디렉션을 사용하여 스크립트의 표준 출력을 캡처합니다. 예 /path/to/output.log
:
/path/to/the/script.py > /path/to/output.log
답변2
이 질문이 오래되었다는 것을 알고 있지만 제가 사용한 검색에서 이 질문이 먼저 나왔기 때문에 Stack OVERflow(https://stackoverflow.com/questions/14906764/how-to-redirect-stdout-to-both-file-and-console-with-scripting):
다음 함수를 제거하고 std를 터미널 및 출력 파일로 연결하는 스크립트를 호출하십시오. 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()