Pump 命令输出作为函数参数

Pump 命令输出作为函数参数

我的脚本中有这个非常简单的函数:

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

这个想法是能够在一个地方自定义/关闭日志记录。非常粗糙。

现在我希望我的脚本在发布配置中完全不产生输出。我想到的唯一解决方案,但非常不干燥:

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

为了每一个命令。对此如何改进呢?


编辑:我想收集全部输出到stdoutstderr并通过 进行引导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

这将影响 shell 本身以及它之后执行的任何命令。有条件地运行该命令以选择输出重定向的位置。

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

尽管请注意,使用 shell 循环处理输出并不是一个好主意,但至少它很慢。看:为什么使用 shell 循环处理文本被认为是不好的做法?。如果您想要的只是重定向一个文件,或者重定向到/dev/null,只需使用exec设置重定向。

相关内容