Вывести время в файл с помощью команды unix «время», но оставить вывод команды на консоли - PullRequest
0 голосов
/ 16 февраля 2020

Я время команды, которая имеет некоторые выходные данные. Я хочу вывести реальное время из команды времени в файл, но оставить вывод команды на консоли.

Например, если я наберу time my_command, я получу печать в консоли

several lines of output from my_command ... 
real 1m25.970s
user 0m0.427s
sys 0m0.518s

В этом случае я хочу сохранить только 1m25.970s в файле, но все равно вывести на консоль вывод команды.

1 Ответ

0 голосов
/ 16 февраля 2020

Команда time хитрая. Спецификация POSIX time не определяет формат вывода по умолчанию, но определяет формат для опции -p (предположительно для POSIX). Обратите внимание на (непонятно) обсуждение последовательности команд в конвейерах.

Спецификация Bash говорит, что time ставит префикс 'pipe' , что означает, что time cmd1 | cmd2 умножено на оба cmd1 и cmd2. Он записывает свои результаты в стандартную ошибку. Оболочка Korn похожа.

Формат POSIX требует одного пробела между тегами, такими как real и временем; формат по умолчанию часто использует вкладку вместо пробела. Обратите внимание, что команда /usr/bin/time может иметь еще один выходной формат. Это происходит в macOS, например, перечисление 3 раза в одной строке по умолчанию с меткой после значения времени; он поддерживает -p для печати в приближении к формату POSIX (но имеет несколько пробелов между меткой и временем).

Вы можете легко получить всю информацию, записанную со стандартной ошибкой, в файл:

(time my_command) 2> log.file

Если my_command или какие-либо программы, которые он вызывает, сообщают о любых ошибках к стандартной ошибке, они также попадают в файл журнала. И вы получите все три строки вывода из time, записанные в файл.

Если ваша оболочка Bash, вы можете использовать подстановка процесса для фильтрации некоторых вывода.

Я бы не стал пробовать это с одной командной строкой; иероглифы, необходимые для его работы, ужасно и лучше всего инкапсулированы в сценарии оболочки.

Например, сценарий оболочки time.filter для захвата вывода из time и записи только real времени в журнал file (по умолчанию log.file, настраивается путем предоставления альтернативного имени файла журнала в качестве первого аргумента

#!/bin/sh

output="${1:-log.file}"
shift
sed -E '/^real[[:space:]]+(([0-9]+m)?[0-9]+[.][0-9]+s?)/{ s//\1/; w '"$output"'
        d;}
        /^(user|sys)[[:space:]]+(([0-9]+m)?[0-9]+[.][0-9]+s?)/d' "$@"

Это предполагает, что sed использует -E для включения расширенных регулярных выражений. Первая строка скрипта находит строку, содержащую метку real и время после нее (в ряде возможных форматов - но не во всех) .Она принимает необязательное значение минут, например 60m05.003s, или просто значение секунд 5.00s, или просто 5.0 (форматы POSIX - как минимум один ди git после десятичной запятой). Он захватывает часть времени и печатает ее в выбранный файл (по умолчанию log.file; вы можете указать альтернативное имя в качестве первый аргумент в командной строке.) Обратите внимание, что даже GNU sed обрабатывает все после команды w как имя файла, вы должны продолжить d (удаление) команда и закрывающая скобка } на новой строке. GNU sed не требует запятой после d; BSD (macOS) sed делает. Вторая строка распознает и удаляет строки отчета в user и sys раз. Все остальное передается неизменным.

Сценарий обрабатывает любые файлы, которые вы ему даете после имени файла журнала или стандартного ввода, если вы его не указали. Лучшая система обозначений командной строки будет использовать явную опцию (-l logfile) и getopts для указания файла журнала.

Имея это, мы можем разработать программу, которая сообщает о стандартной ошибке и стандартном выводе - my_command:

echo "nonsense: error: positive numbers are required for argument 1" >&2
dribbler -s 0.4 -r 0.1 -i data -t
echo "apoplexy: unforeseen problems induced temporary amnesia" >&2

Вы можете использовать cat data вместо команды dribbler. Команда dribbler, как показано, читает строки из data, записывает их в стандартный вывод со случайной задержкой с гауссовым распределением между строками. Средняя задержка составляет 0,4 секунды; стандартное отклонение составляет 0,1 секунды. Две другие строки претендуют на то, чтобы быть командами, которые сообщают об ошибках стандартной ошибке.

Мой data файл содержал бессмысленную поэму под названием 'The Great Panjandrum' .

С этим фоном мы можем запустить команду и зафиксировать реальное время в log.file, удалить (игнорировать) значения времени пользователя и системы, отправив остаток стандартной ошибки в стандартную ошибку, используя:

$ (time my_command) 2> >(tee raw.stderr | time.filter >&2)
nonsense: error: positive numbers are required for argument 1
So she went into the garden
to cut a cabbage-leaf
to make an apple-pie
and at the same time
a great she-bear coming down the street
pops its head into the shop
What no soap
So he died
and she very imprudently married the Barber
and there were present
the Picninnies
and the Joblillies
and the Garyulies
and the great Panjandrum himself
with the little round button at top
and they all fell to playing the game of catch-as-catch-can
till the gunpowder ran out at the heels of their boots
apoplexy: unforeseen problems induced temporary amnesia

$ cat log.file
0m7.278s
$

(Обычно это занимает от 6 до 8 секунд. Всего 17 строк, поэтому можно ожидать, что оно займет около 6,8 секунд при 0,4 секундах на линию. ) Пустая строка от time; удалить эту пустую строку довольно сложно, и только эту пустую строку, особенно если POSIX говорит, что это необязательно. Это не стоит того.

...