Перенаправьте терминальный вывод в файл

Я ищу a bash управляйте, где я могу перенаправить:

  1. stdout команды в файл
  2. stderr и в тот файл и в консоль.

Я нашел способы, где stderr добавит в конец файла после stdout, но я хочу его так, чтобы выходной файл заказал все, что вывод хронологически как он был бы, если я должен был просто использовать command &> file.

Я попробовал:

command 2>&1 1>logfile | tee -a logfile
command 2> >(tee -a logfile) 1>>logfile

Я в основном хотел бы, чтобы выходной файл был тем же, как будто я просто сделал command &> logfile, пока одновременно продолжают печатать сообщения stderr к консоли.

0
задан 12 June 2018 в 12:47

4 ответа

Давайте создадим тестовую функцию, которая отправляет некоторый вывод и в stdout и в stderr:

$ cmd() { echo 1 on stdout; echo 2 on stderr >&2; echo 3 on stdout; echo 4 on stderr >&2; }

Выполнение его мы видим:

$ cmd
1 on stdout
2 on stderr
3 on stdout
4 on stderr

Теперь, мы хотим отправить stdout в файл и stderr и в файл и в экран. Для этого мы используем простое перенаправление для stdout, и для stderr мы перенаправляем в замену процесса, которая добавляет в файл и передает вывод обратно stderr:

$ cmd > cmd.out 2> >( tee -a cmd.out >&2 )
2 on stderr
4 on stderr

$ cat cmd.out
1 on stdout
3 on stdout
2 on stderr
4 on stderr

Я не знаю о способе сохранить хронологический порядок смешанного stdout и сообщений stderr.

2
ответ дан 29 October 2019 в 03:16

Я не думаю, что можно действительно сделать это.

Когда Вы перенаправляете stdout и stderr отдельно, они становятся несинхронизируемыми, и нет никакого способа зафиксировать их назад снова. То, что Вы пытаетесь сделать, является чем-то вроде этого:

                  +------> terminal
                  |       
cmd -(stderr)--> tee ----> file
 |                          ^
 +---(stdout)---------------+      

Здесь, существует два параллельных пути от cmd кому: file, с дополнительным процессом в stderr путь. В зависимости от планирования могли бы быть задержки пути, который включает tee, который может и приводить к stderr сообщения отложены.

Для предотвращения этого система должна была бы переключиться на tee сразу, когда это вводится. Обычно, на это нельзя рассчитывать, чтобы сделать это. Добавление другого процесса к параллельному пути не поможет, поскольку затем результат будет просто зависеть от планирования между двумя промежуточными процессами (вместо cmd и tee).

0
ответ дан 29 October 2019 в 03:16

Это работает, если Вы добавляете stdout в файл и перенаправляете stderr к tee, также добавляя в файл:

$ bash -c "echo a;bahs;echo b;bhas" >>file 2> >( tee -a file >&2 )
bash: bahs: command not found
bash: bhas: command not found
$ cat file
a
bash: bahs: command not found
b
bash: bhas: command not found

Это не работает с тестом из ответа glenn jackman, и я не могу перенести голову почему.

0
ответ дан 29 October 2019 в 03:16

Вы можете сделать что-то вроде этого:

echo "asd" | xargs -I % sh -c 'echo % && echo % > asd'

Первое эхо передается в xargs, который принимает его в качестве аргумента и создает две команды эха, первый результат выводится на терминал, а второй - в файл назван также asd как текст.

Вы можете установить переадресацию после, чтобы соответствовать вашим потребностям.

0
ответ дан 20 February 2020 в 11:08

Другие вопросы по тегам:

Похожие вопросы: