Перенаправление stderr и stdout отдельно для функции в сценарии bash

Решение

Файл /etc/nsswitch.conf должен присутствовать и содержать следующую строку:

    hosts: dns files

В моем случае это было решено. Не знаю почему, но там было пусто!

5
22.01.2018, 01:50
2 ответа

Esto es lo que estoy usando para redirigir por separado stderr y stdout a una función:

tag() { awk '$0="['$1'] "$0; fflush();' ; }

{
    {
        echo std1; sleep 0.1;
        echo error2 >&2; sleep 0.1;
        echo error3 >&2; sleep 0.1;
        echo std4; sleep 0.1;
    } 2>&1 1>&3 | tag STDERR 1>&2 ;
} 3>&1 | tag STDOUT 3>&- ;

Esto debería dar el siguiente resultado:

[STDOUT] std1
[STDERR] error2
[STDERR] error3
[STDOUT] std4

Me funciona en bash y ksh (93u+ ).

Tenga en cuenta que agrego "dormir 0.1" entre comandos para preservar el orden de las líneas en ese caso.

1
27.01.2020, 20:35

Вы можете просто использовать подстановку процессов непосредственно в перенаправлениях:

gen > >(one) 2> >(two)

Это даст стандартный вывод genв качестве стандартного ввода для oneи стандартную ошибку genв качестве ввода для two. Это могут быть исполняемые команды или функции; вот функции, которые я использовал:

one() {
    while read line
    do
        echo $'\e[31m'"$line"$'\e[22m'
    done
}

two() {
    while read line
    do
        echo $'\e[32m'"$line"$'\e[22m'
        echo "$line" >&2
    done
}

Они выводят свои входные строки красным и зеленым цветом соответственно, а twoтакже записывают с обычной стандартной ошибкой. Вы можете делать все, что хотите, внутри циклов или отправлять ввод в другую программу или что угодно.


Обратите внимание, что на самом деле не существует такой вещи, как "сохранение порядка строк", когда вы находитесь в этой точке-это два отдельных потока и отдельных процесса, и вполне возможно, что планировщик запускает один процесс некоторое время, прежде чем он даст другой ход, с данными, хранящимися в буфере канала ядра, пока они не будут прочитаны. Я использую функцию, выводящую нечетные числа на стандартный вывод и даже на стандартный вывод для тестирования, и обычно получается дюжина или более подряд из каждого.

Можно было бы получить что-то более близкое к порядку, как он появляется в терминале, но, вероятно, не в Bash. Программа на языке C, использующаяpipeи select, может восстановить порядок (, хотя не гарантируется, что он будет таким же, как показано,по той же причине :ваш процесс может какое-то время не планироваться, а когда возникает отставание, невозможно сказать, что было раньше 1). Если порядок жизненно важен, вам понадобится другой подход и, вероятно, сотрудничество с базовым исполняемым файлом. Если это сложное требование, вам, возможно, придется пересмотреть свое решение.

1Также могут существовать специфические для платформы -методы управления буферизацией канала, но вряд ли они помогут вам в достаточной мере. В Linux вы можете уменьшить размер буфера до размера системной страницы, но не меньше. Я не знаю ни одного, который позволяет принудительно выполнять запись немедленно (или блокировать до тех пор, пока они не будут прочитаны ). В любом случае, они вполне могут быть буферизованы на исходном конце подобно потокам stdio, и тогда вы никогда не увидите порядка.

9
27.01.2020, 20:35

Теги

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