С bash, как я могу передать стандартную ошибку в другой процесс?
Хорошо известно, как подключить стандартный вывод процесса к другому стандартным вводам процессов:
proc1 | proc2
Но что, если я хочу отправить стандартную ошибку proc1 в proc2 и оставить стандартный вывод в текущем местоположении? Вы думаете, что bash
будет иметь команду по строкам:
proc1 2| proc2
Но, увы, нет. Есть ли способ сделать это?
Ответы
Ответ 1
Вы можете использовать следующий трюк для обмена stdout
и stderr
. Тогда вы просто используете обычную функциональность трубы.
( proc1 3>&1 1>&2- 2>&3- ) | proc2
Если stdout
и stderr
оба указывают на одно и то же место в начале, это даст вам то, что вам нужно.
Бит x>y
делает для изменения дескриптора файла x
чтобы он теперь отправлял свою информацию туда, куда в данный момент указывает дескриптор файла y
Для нашего конкретного случая:
-
3>&1
создает новый дескриптор 3
который будет выводиться на текущий дескриптор 1
(исходный стандартный вывод), просто чтобы сохранить его где-нибудь для последнего пункта маркера ниже. -
1>&2
изменяет дескриптор 1
(stdout) для вывода на текущий дескриптор 2
(оригинальный stderr). -
2>&3-
изменяет дескриптор 2
(stderr) для вывода на текущий дескриптор 3
(оригинальный stdout), затем закрывает дескриптор 3
(через -
в конце).
Это эффективно команда подкачки, которую вы видите в алгоритмах сортировки:
temp = value1;
value1 = value2;
value2 = temp;
Ответ 2
Существует также замена процесса. Это делает процесс заменой файла.
Вы можете отправить stderr
в файл следующим образом:
process1 2> file
Но вы можете заменить процесс для файла следующим образом:
process1 2> >(process2)
Вот конкретный пример, который отправляет stderr
на экран и добавляет в файл журнала
sh myscript 2> >(tee -a errlog)
Ответ 3
Bash 4 имеет эту функцию:
Если `| & ', стандартная ошибка команды 1 связана с стандартным вводом команды 2 через трубу; это сокращенно 2 > & 1 |. Это неявное перенаправление стандартной ошибки выполняется после любых переназначений, указанных в команде.
zsh также имеет эту функцию.
-
С другими/старыми оболочками просто введите это явно как
FirstCommand 2 > & 1 | OtherCommand
Ответ 4
Перемещение отлично, поскольку оно решает проблему. На всякий случай, когда вам даже не понадобится исходный stdout, вы можете сделать это следующим образом:
proc1 2>&1 1>/dev/null | proc2
Порядок важен; вам не нужно:
proc1 >/dev/null 2>&1 | proc1
Так как это перенаправит все на /dev/null
!
Ответ 5
Ни один из них действительно не работал очень хорошо. Лучший способ сделать то, что вы хотели, это:
(command < input > output) 2>&1 | less
Это работает только в тех случаях, когда command
не требует ввода с клавиатуры. например:
(gzip -d < file.gz > file) 2>&1 | less
поместил бы ошибки gzip в меньше