Возможно ли шаблонизировать/перезаписать STDOUT?

Возможно ли шаблонизировать/перезаписать STDOUT?

Я отлаживаю стек вызовов и просто вывожу echoоператоры из разных файлов. Плоские журналы становятся немного сложными для понимания, поэтому мне интересно, какой может быть лучший способ вложения вывода.

Я думал, что установка переменной окружения либо на количество табов, либо в качестве префиксной строки пробела/табуляции может быть самым простым вариантом, если я могу перегрузить поток STDOUT. В принципе, было бы неплохо, если бы я мог сделать что-то вроде STDOUT="$TABS$STDOUT"сохранения стекирования символов табуляции в начале выходного потока.

Но я не был уверен, возможно ли вообще перезаписать поток? Например, если я хочу добавить к каждой строке префикс дефис+пробел, возможно ли это?

Таким образом, что:

echo foo
echo bar
echo foobar

Производит:

- foo
- bar
- foobar

  1. Возможно ли шаблонизировать STDOUT?
  2. Какой метод предлагается для вложенного вывода, без необходимости изменять все операторы echo/ printfво многих различных скриптах, которые могут быть вызваны?

решение1

Вероятно, самое простое, что можно сделать, если вы не против объединения stdout и stderr, это запустить с флагом, -xкоторый заставляет bash печатать каждую команду по мере ее выполнения с префиксом, например, +++где количество символов берется из уровня вложенности. Затем вы можете выполнить постобработку вывода, запомнив префикс, но подавив строку, и применить его к любой следующей строке без префикса, которая и будет вашим echo или printf.

Например, возьмем небольшой факториальный скрипт myprog:

#!/bin/bash
f(){
        local i=$1
        if [[ "$i" > 1 ]]
        then        echo $((i*$(f $((i-1)))))
        else        echo $i
        fi
        echo "my debug info $i" >&2
}
echo "factorial ${1?} is $(f $1)"

Запуск с помощью

 bash -x myprog 4  |&
 awk '/^+/{ indent=$1; next }
          { print indent " " $0 }'

дает тебе

+++++ my debug info 1
++++ my debug info 2
+++ my debug info 3
++ my debug info 4
+ factorial 4 is 24

Конечно, вы можете получить довольно хороший отладочный вывод с номерами строк, именами файлов и функциями, просто установив PS4с помощью -x. Например

PS4='+ ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]} - [${SHLVL},${BASH_SUBSHELL}, $?]     ' 

дает тебе:

++ myprog:10: main - [2,1, 0]     f 4
++ myprog:3: f - [2,1, 0]     local i=4
++ myprog:4: f - [2,1, 0]     [[ 4 > 1 ]]
+++ myprog:5: f - [2,2, 0]     f 3
+++ myprog:3: f - [2,2, 0]     local i=3
+++ myprog:4: f - [2,2, 0]     [[ 3 > 1 ]]
++++ myprog:5: f - [2,3, 0]     f 2
++++ myprog:3: f - [2,3, 0]     local i=2
++++ myprog:4: f - [2,3, 0]     [[ 2 > 1 ]]
...

Связанный контент