2013-11-18 4 views
4

У меня есть команда, производящая вывод, принадлежащий разным командам.Как захватить вывод нескольких команд?

s=$(time dd if=<source> of=/dev/null bs=<number> count=<number> 2>&1) 

$s будет содержать выход только из команды dd. Как я могу получить другую переменную, которая будет содержать результат от time?

+2

http://stackoverflow.com/q/3928430/469220 – Vlad

+0

Вы также можете использовать '/ USR/BIN/time' или'/bin/time' вместо оболочки встроенной. Это регулярная команда, которая следует за регулярными правилами перенаправления. Построенное '' '' 'bash' немного странно, как вы обнаружили. –

+0

@ Джонатан, спасибо за комментарий. Я могу использовать только встроенную команду. – yart

ответ

3

Попробуйте следующее:

s=$({ time dd ... > /dev/null;} 2>&1) 

Chepners ответ дал мне вдохновение для, возможно, лучше:

s=$(exec 2>&1; time dd ... > /dev/null) 

$() не уже подоболочка, поэтому нет необходимости создавать дополнительную подоболочку. Помещение exec 2>&1; перед командой перенаправляет stdout всей подоболочки, поместив ее после того, как команда сделает ее частью команды до time и, следовательно, будет применена только к команде, переданной в time. Опуская exec и точку с запятой попытается выполнить двоичный код системы time, а также ошибку, если этого не существует. Опуская только exec, но сохранение точки с запятой не будет работать, так как это приведет к перенаправлению только новых разветвленных процессов, а встроенное время не будет новым процессом.

Да, и кстати, > /dev/null не сбрасывает выход самого time в/DEV/нуль, потому что это тоже часть команды, которая time выполняется и не применяется к самому времени.

+0

@ JonathanLeffler, 's = $ (exec 2> & 1; time dd if = something of =/dev/null)' было бы действительно более предсказуемым поведением ;-) – thom

+0

Тихо меня игнорировать ... Я ошибся, что вы указали. –

+0

@which, я пробовал вашу команду: s = $ (2> и 1 раз >/dev/null), и он возвращает, -sh: time: command не найден.У меня GNU bash, версия 4.1.5. – yart

1

Здравствуйте, я просто узнаю ответ.

Ссылка от Влада в комментариях дала мне направление.

Я могу использовать подоболочки.

Моя команда может быть указана

s=$((time dd if=<source> of=/dev/null bs=<number> count=<number> 2>&1 | tail -n1) 2>&1) 

Тогда я могу иметь $ s переменный, содержащие все данные, и я могу иметь массив и получить значение.

+0

's = $ ({time date;} 2> & 1)' также будет работать нормально – anubhava

1

bash встроенный time - это специальная встроенная программа, которая записывает стандартную ошибку текущей оболочки, поэтому вы не можете просто перенаправить свой вывод. Вместо этого вам нужно будет запустить его в подоболочке, стандартная ошибка которой уже перенаправлена. Это приводит к тому, что команда «real» добавляет также в подоболочку, поэтому вы не можете просто назначить свой вывод переменной, так как эта переменная исчезнет с подоболочкой. Попробуйте это:

s=$(exec 2>time.txt; time echo foo) 
t=$(< time.txt) 
Смежные вопросы