Система не использует магию, указатель файла , такой как stdout и stderr , должен обрабатываться вашим кодом по-разному. Например, stdout является одним из указателей файла, вы можете сделать это ниже:
log_file_pointer = open('log.txt', 'wt')
print('print_to_fp', file=log_file_pointer)
# Note: the print function will actually call log_file_pointer.write('print_to_fp')
Исходя из ваших требований, вы хотите, чтобы волшебная функция обрабатывала более одного указателя файла в одной строке, вам нужна функция-обёртка ниже:
def print_fps(content, files=[]):
for fi in files:
print(content, file=fi)
# the argument `file` of print does zero magic, it can only handle one file pointer once.
Затем, вы можете сделать магию сейчас (сделать вывод как на экране, так и в файле.)
import sys
log_file_pointer = open('log.txt', 'wt')
print_fps('1. Before', files=[log_file_pointer, sys.stdout])
print_fps('\n2. After', files=[log_file_pointer, sys.stdout])
После завершения части print
перейдем к системному вызову. Запустив любую команду в операционной системе, вы получите возврат в указателях системных файлов по умолчанию: stdout и stderr . В python3 вы можете получить эти результаты в байтах с помощью подпроцесса. Откройте . И при выполнении кода ниже, что вы хотите, должен быть результат в stdout .
import subprocess
p = subprocess.Popen("whoami", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
# stdout: b'user01'
# stdout: b''
Еще раз, вы можете вызвать функцию-обёртку, написанную выше, и сделать вывод как в stdout, так и в target__inter_tinter.
print_fps(stdout, files=[log_file_pointer, sys.stdout])
Наконец, объединяя весь код выше. (Плюс еще одна удобная функция.)
import subprocess, sys
def print_fps(content, files=[]):
for fi in files:
print(content, file=fi)
def get_stdout(command):
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
# Note: Original idea is to return raw stdout
# return stdout
# Based on the scenario of the @Sabrina, the raw bytes of stdout needs decoding in utf-8 plus replacing newline '\r\n' to be pure
return stdout.decode().replace('\r\n', '')
log_file_pointer = open('log.txt', 'wt')
print_fps('1. Before', files=[log_file_pointer, sys.stdout])
print_fps(get_stdout('ver'), files=[log_file_pointer, sys.stdout])
print_fps(get_stdout('whoami'), files=[log_file_pointer, sys.stdout])
print_fps('\n2. After', files=[log_file_pointer, sys.stdout])
- Примечание: поскольку вывод Popen в байтах, вам может потребоваться выполнить декодирование, чтобы удалить b '' . Вы можете запустить stdout.decode () для декодирования байтов в декодированную строку utf-8. *