Во-первых, за некоторыми исключениями перераспределение обычно происходит в том месте, где они написаны. Они удаляются из последовательности команд и аргументов; участвуют только остальные, непереадресованные слова. Таким образом:
3>&1 foo 1>&2 arg1 2>&3 arg2 3>&- arg3
работает foo arg1 arg2 arg3
с стандартным выводом и стандартным потоком ошибок выгружены, потому что:
3>&1
делает копию (точнее, dup2
) ФД 1 (стандартный вывод) на дескрипторе 3
1>&2
марки копия fd 2 (stderr) на fd 1 (так что теперь stdout и stderr оба идут туда, куда бы они ни направлялись)
2>&3
делает копию fd 3 (сохраненный исходный stdout) на fd 2 (stderr)
3>&-
закрывает Fd 3.
(Заметным исключением является то, что конвейерный выход «происходит первый», даже если символ трубы в конце простой командной части.)
Во-вторых, поскольку pje отметил, time
- это встроенный баш. time foo
запускает команду, затем печатает сводку времени для stderr bash. Ключевое слово time
эффективно удаляется первым, затем оставшаяся последовательность команд обрабатывается, как обычно. (Это применимо, даже если команда является конвейером: time
раз весь трубопровод.)
В этом случае последовательность команд является одна простой командой, с переадресациями:
2>&1 sh 2>&1 -c ... > file
Каждого Перенаправление происходит в точке написано, а оставшаяся последовательность:
sh -c ...
Перенаправлениями являются:
- отправьте stderr туда, куда stdout в настоящее время собирается
- отправить stderr в stdout, снова (это не имеет никакого эффекта)
- отправьте stdout на номер
file
.
так sh -c
запускается с его STDERR будет ваш стандартный вывод, а его стандартный вывод собирается подать file
. Как вы заметили, dd
выводит свой вывод на stderr, который является stderr sh -c ...
, который является вашим стандартом.
При запуске:
time 2>file dd if=/dev/zero of=ddfile bs=512 count=125
вы получите time
's выход Stderr на вашем STDERR (например, экран), и dd
' s STDERR в файле file
. (Это происходит независимо от того, насколько правильно вы слайд 2>file
части, до тех пор, пока она остается частью простой команды.)
Если попробовать:
2>file time ...
вы найдете выход time
«s перенаправлен , но это полностью побеждает встроенный time
, вместо этого работает /usr/bin/time
. Чтобы получить встроенный баш-бит, time
должен быть впереди. Вы можете сделать подоболочку:
(time ...) 2>file
или подблок как pje illustrated:
{ time ...; } 2>file
(синтаксис является неуклюжим с субблоком в виде белого пространства и/или запятой необходимы, но он избегает системного вызова fork
).
связанные? http://stackoverflow.com/questions/2408981/how-cant-i-redirect-the-output-of-time-command – pje