2014-09-21 3 views
1

есть subprocess.call(["ddrescue", in_file_path, out_file_path], stdout=drclog). Мне бы хотелось, чтобы это отображало ddrescue в терминале по мере его запуска и записывало вывод в файл drclog. Я пробовал использовать subprocess.call(["ddrescue", in_file_path, out_file_path], stdout=drclog, shell=True), но это дает мне ошибку ввода в ddrescue.Как вывести вывод subprocess.call() в терминал и файл?

+0

Что вы понимаете, показывая ddrescue в терминале? – kraskevich

+0

ddrescue показывает процесс копирования в этом формате; 'ГНУ ddrescue 1.18.1 Нажмите Ctrl-C, чтобы прервать спасенного: 0 B, errsize: 0 В, текущая скорость: 0 B/S IPOS: 0 В, ошибки: 0, средняя оценка: 0 B/S opos: 0 B, время работы: 1 с, успешное чтение: 1 сек назад Закончено' Я хотел бы иметь возможность видеть это и иметь окончательный статус, записанный в файл (stdout). – p014k

+0

Если вы хотите что-то написать в терминал и файл одновременно, вы можете использовать команду tee. Я не уверен, что можно записать часть вывода на терминал и часть его в файл, если данные записываются в один выходной поток. – kraskevich

ответ

2

Если ddrescue не меняет свой выход, если ее стандартный вывод/STDERR перенаправляются в трубу, то вы можете использовать утилиту tee, чтобы отобразить вывод на терминал и сохранить его в файл:

$ ddrescue input_path output_path ddrescue_logfile |& tee logfile 

Если это, то вы могли бы попытаться обеспечить псевдо-терминал с помощью утилиты script:

$ script -c 'ddrescue input_path output_path ddrescue_logfile' -q logfile 

Если it writes directly to a terminal, то вы могли бы использовать screen перехватывать вывод:

$ screen -L -- ddrescue input_path output_path ddrescue_logfile 

Выход по умолчанию сохраняется в файле screenlog.0.


Для эмуляции -А команды tee в Python без вызова tee утилиты:

#!/usr/bin/env python3 
import shlex 
import sys 
from subprocess import Popen, PIPE, STDOUT 

command = 'ddrescue input_path output_path ddrescue_logfile' 
with Popen(shlex.split(command), stdout=PIPE, stderr=STDOUT, bufsize=1) as p: 
    with open('logfile', 'wb') as logfile: 
     for line in p.stdout: 
      logfile.write(line) 
      sys.stdout.buffer.write(line) 
      sys.stdout.buffer.flush() 

Для вызова -А команде tee в Python с использованием shell=True:

#!/usr/bin/env python 
from pipes import quote 
from subprocess import call 

files = input_path, output_path, ddrescue_logfile 
rc = call('ddrescue {} | tee -a drclog'.format(' '.join(map(quote, files))), 
      shell=True) 

Чтобы эмулировать script -направленная команда:

#!/usr/bin/env python3 
import os 
import shlex 
import pty 

logfile = open('logfile', 'wb') 
def read(fd): 
    data = os.read(fd, 1024) # doesn't block, it may return less 
    logfile.write(data) # it can block but usually not for long 
    return data 
command = 'ddrescue input_path output_path ddrescue_logfile' 
status = pty.spawn(shlex.split(command), read) 
logfile.close() 

Для вызова screen команды в Python:

#!/usr/bin/env python3 
import os 
import shlex 
from subprocess import check_call 

screen_cmd = 'screen -L -- ddrescue input_path output_path ddrescue_logfile' 
check_call(shlex.split(screen_cmd)) 
os.replace('screenlog.0', 'logfile') 
+0

Как python обрабатывает '{}'? Например, в 'call ('ddrescue {} | tee -a drclog' ...' – p014k

+0

напечатайте команду и убедитесь сами. – jfs

+0

В этом ответе слишком много разных подходов. Я считаю, что это неконструктивно для сообщества. Ответ, который работал, - это просто 'subprocess.call ('ddrescue {} | tee -a drclog'.format (' .join (map (quote, files))), shell = True)' part. – p014k

-1

Решение, которое работало для меня было subprocess.call(["ddrescue $0 $1 | tee -a drclog", in_file_path, out_file_path], shell=True).

+1

неверно. 2-й и 3-й аргументы - 'bufsize' и' executable', а не файлы. – jfs

+0

Он отлично работает, хотя ... – p014k

+1

-1: код повышает TypeError – jfs

Смежные вопросы