Как я могу достичь
cmd >> file1 2>&1 1>>file2
То есть stdout и stderr должны перенаправлять на один файл (file1), и только stdout (file2) должен перенаправлять на другой (оба в режиме добавления)?
Как я могу достичь
cmd >> file1 2>&1 1>>file2
То есть stdout и stderr должны перенаправлять на один файл (file1), и только stdout (file2) должен перенаправлять на другой (оба в режиме добавления)?
Ответы:
Проблема в том, что когда вы перенаправляете свой вывод, он больше не доступен для следующего перенаправления. Вы можете передать tee
в подоболочку, чтобы сохранить выходные данные для второго перенаправления:
( cmd | tee -a file2 ) >> file1 2>&1
или если вы хотите увидеть вывод в терминале:
( cmd | tee -a file2 ) 2>&1 | tee -a file1
Чтобы не добавлять stderr первого tee
в file1
, вы должны перенаправить stderr вашей команды в некоторый файловый дескриптор (например, 3), а затем снова добавить это в stdout:
( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1
(спасибо @ фра-сан)
С zsh
:
cmd >& out+err.log > out.log
В режиме добавления:
cmd >>& out+err.log >> out.log
В zsh
и при условии, что mult_ios
опция не была отключена, когда дескриптор файла (здесь 1) перенаправляется несколько раз для записи, тогда оболочка реализует встроенную функцию tee
для дублирования вывода для всех целей.
cmd >& file1 > file2
Вы можете: пометить stdout (используя UNBUFFERED sed, то есть:) sed -u ...
, заставить stderr также перейти к stdout (без тегов, так как он не прошел через это пометку sed), и, таким образом, иметь возможность различать 2 в результирующем лог-файле.
Следующее: медленно (его можно серьезно оптимизировать, используя для примера сценарий perl вместо while ...; do ...; done, для примера, который будет порождать подоболочки и команды в каждой строке!), Странно (кажется, мне нужно 2 {} этапов для того, чтобы в одном stdout переименовать, а затем в другом добавить к нему stderr «свернул») и т. д. Но это: « доказательство концепции », которое будет пытаться сохранить порядок вывода максимально возможного количества stdout & stderr:
#basic principle (some un-necessary "{}" to visually help see the layers):
# { { complex command ;} | sed -e "s/^/TAGstdout/" ;} 2>&1 | read_stdin_and_redispatch
#exemple:
# complex command = a (slowed) ls of several things (some existing, others not)
# to see if the order of stdout&stderr is kept
#preparation, not needed for the "proof of concept", but needed for our specific exemple setup:
\rm out.file out_AND_err.file unknown unknown2
touch existing existing2 existing3
#and the (slow, too many execs, etc) "proof of concept":
uniquetag="_stdout_" # change this to something unique, that will NOT appear in all the commands outputs...
# avoid regexp characters ("+" "?" "*" etc) to make it easy to remove with another sed later on.
{
{ for f in existing unknown existing2 unknown2 existing3 ; do ls -l "$f" ; sleep 1; done ;
} | sed -u -e "s/^/${uniquetag}/" ;
} 2>&1 | while IFS="" read -r line ; do
case "$line" in
${uniquetag}*) printf "%s\n" "$line" | tee -a out_AND_err.file | sed -e "s/^${uniquetag}//" >> out.file ;;
*) printf "%s\n" "$line" >> out_AND_err.file ;;
esac;
done;
# see the results:
grep "^" out.file out_AND_err.file
ls unknown
) для печати чего-либо на stderr? >&2 echo "error"
было бы хорошо. (2) tee
можно добавлять к нескольким файлам одновременно. (3) Почему бы не просто cat
вместо grep "^"
? (4) ваш скрипт потерпит неудачу, когда вывод stderr начнется с _stdout_
. (5) почему?
ls loop
будет выводить как на stdout, так и на stderr, смешанные (альтернативно), в контролируемом порядке, чтобы мы могли проверить, что мы сохранили порядок stderr / stdout, несмотря на пометку stdout 2): возможно, gnu tail, но не регулярный хвост (напр., на aix.). 3): grep "^" также показывает оба имени файла. 4): это может быть изменено переменной. 5): извилистый пример работает на старых oses (ex, old aix), где я его тестировал (нет доступных perl).
uniquetag="banaNa11F453355B28E1158D4E516A2D3EDF96B3450406
...)
Если порядок вывода должен быть следующим: stdout, то stderr ; нет решения только с перенаправлением.
Stderr должен быть сохранен во временном файле
cmd 2>>file-err | tee -a file1 >>file2
cat file-err >> file1
rm file-err
Описание:
Единственный способ перенаправить один вывод (например, stdout или stderr) на два файла - это воспроизвести его. Команда tee
является правильным инструментом для воспроизведения содержимого файлового дескриптора. Итак, первоначальной идеей иметь один вывод для двух файлов было бы использовать:
... | tee file1 file2
Это воспроизводит stdin of tee для обоих файлов (1 и 2), оставляя выходные данные tee по-прежнему неиспользованными. Но нам нужно добавить (использовать -a
) и только одну копию. Это решает обе проблемы:
... | tee -a file1 >>file2
Чтобы предоставить tee
stdout (тот, который нужно повторить), нам нужно использовать stderr непосредственно из команды. С одной стороны, если порядок не важен (порядок вывода (скорее всего) будет сохранен как сгенерированный, в зависимости от того, что выводится первым, он будет сохранен первым). Или:
cmd 2>>file1 | tee -a file2 >>file1
cmd 2>>file1 > >( tee -a file2 >>file1 )
( cmd | tee -a file2 ) >> file1 2>&1
Вариант 2 работает только в некоторых оболочках. Вариант 3 использует дополнительную подоболочку (медленнее), но использует имена файлов только один раз.
Но если stdout должен быть первым (какой бы вывод заказа не был сгенерирован), нам нужно сохранить stderr, чтобы добавить его в файл в конце (первое опубликованное решение).
sponge
делает:(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
В интересах разнообразия:
Если ваша система поддерживает /dev/stderr
, то
(cmd | tee -a /dev/stderr) 2>> file1 >> file2
буду работать. Стандартный вывод команды cmd
отправляется как в stdout, так и в stderr конвейера. Стандартная ошибка cmd
обходит tee
и выходит из stderr конвейера.
Так
cmd
, иcmd
смешанного.Тогда просто отправить эти потоки в правильные файлы.
Как и в случае почти любого подобного подхода (включая ответ Стефана ),
file1
строки могут быть не в порядке.
out+err
иout
что здесь значит. Имена файлов? Потоки будут перенаправлены?