Вывод команды насоса как аргумент функции

Вывод команды насоса как аргумент функции

В моем скрипте есть эта чрезвычайно простая функция:

# Used for debug tracing.
log()
{
    :
    echo "log: $1"
}

Идея в том, чтобы иметь возможность настраивать/отключать ведение журнала в одном месте. Очень грубо.

Теперь я хочу, чтобы мой скрипт не производил абсолютно никакого вывода в конфигурации релиза. Единственное решение, которое я придумал, но крайне неСУХОЕ:

TMPFILE='/tmp/tempfilewithpossiblyuniquename'
cmd 1>"$TMPFILE" 2>"$TMPFILE"
cat "$TMPFILE" | xargs log
rm "$TMPFILE"

длякаждая команда. Как это улучшить?


EDIT: Я хочу собратьвсевывести в stdoutи stderrи направить его через log(). Затем log()можно выбрать игнорировать все, записать в файл, распечатать и т. д.

решение1

Во-первых, эта функция будет регистрировать только первое «слово» всего отправленного ей сообщения, поскольку вы используете $1вместо "$*".

Во-вторых, есть (как это часто бывает с POSIX) множество способов сделать что-то подобное. Я бы, наверное, выбрал что-то вроде:

log() {
    cat - >> "$logfile"
}

do_stuff | log

Но вы также можете:

(
    do_stuff
    do_more_stuff
) >> "$logfile"

Что касается полного подавления всего вывода — это то, что обычно лучше оставить для вызывающей среды (например, ./thing 1> /dev/null 2> &1), а не блокировать его «в коде», как это было. При этом:

squashout="true"  # comment this out to stop killing output
if ! [[ "true" = "${squashout-false}" ]]; then 
  # Redirect stdout and stderr to the null device.  
  exec 1> /dev/null
  exec 2> /dev/null
fi

решение2

Абсолютно никакой вывод не является простым, просто перенаправьте скрипты stdoutи stderrна /dev/null:

exec >/dev/null 2>&1

Это повлияет на саму оболочку и любые команды, которые она выполнит после этого. Запустите это условно, чтобы выбрать, куда перенаправлять вывод.

if [ "$output_to_file" = 1 ]; then
    exec > "$outputfilename" 2>&1
elif [ "$output_suppress" = 1 ]; then
    exec > /dev/null 2>&1
fi

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


Если вы настаиваете на передаче вывода через функцию (и используете Bash/ksh/Zsh), вы можете использовать подстановку процесса:

#!/bin/bash
mangle_output() {
    # do something smarter here
    while read -r line; do
        echo "output: $line";
    done;
}
# redirect stdout and stderr to the function
exec > >(mangle_output) 2>&1
echo something that produces output

Хотя следует отметить, что обработка выходных данных с помощью цикла оболочки — не очень хорошая идея, по крайней мере, это медленно. Смотрите:Почему использование цикла оболочки для обработки текста считается плохой практикой?. Если вам нужно только перенаправить файл или на /dev/null, просто используйте execдля настройки перенаправлений.

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