Можно ли передать обычный stdout дальше другой программе, но сохранить stderr в переменной?

Это вариант использования:

mysqldump database | gzip > database.sql

В этом сценарии я хотел бы перехватить все ошибки / предупреждения, создаваемые mysqldump, и сохранить их в переменной, но нормальный stdout (который является дампом) должен по-прежнему передаваться по конвейеру на gzip .

Любые идеи о том, как это сделать?

0
lockdoc 24 Фев 2016 в 14:25

2 ответа

Лучший ответ

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

errors=$(mysqldump database 2>&1 > >(gzip > database.sql))

Здесь я использую подстановку процесса, чтобы заставить gzip использовать вывод mysqldump как стандартный ввод. Учитывая порядок перенаправлений (2>&1 до >), mysqldump Теперь для подстановки команд следует использовать stderr.

Тестирование:

$ a=$(sh -c 'echo foo >&2; echo bar' 2>&1 > >(gzip > foo))
$ gunzip < foo
bar
$ echo $a
foo
2
Community 23 Май 2017 в 11:51

Вы можете сделать следующее:

mysqldump database 2> dump_errors | gzip > database.sql
error_var=$( cat dump_errors )
rm dump_errors

Здесь все ошибки mysqldump перенаправляются в файл с именем 'dump_errors', а stdout передается по конвейеру в gzip, который, в свою очередь, записывает в database.sql.

Затем содержимое dump_errors присваивается переменной error_val, а затем удаляется файл dump_errors.


Обратите внимание на следующие перенаправления:

$ sort 1> output 2> errors   # redirects stdout to "output", stderr to "errors"
$ sort 1> output 2>&1        # stderr goes to stdout, stdout writes to "output"
$ sort 2> errors 1>&2        # stdout goes to stderr, stderr writes to "errors"

$ sort 2>&1 > output         # tie stderr to screen, redirect stdout to "output"
$ sort > output 2>&1         # redirect stdout to "output", tie stderr to "output"
3
assefamaru 24 Фев 2016 в 12:02