从this question我学习了如何为命令的每个输出添加前缀:
command | sed "s/^/[prefix] /"
但这只会为stdout
中的每一行添加前缀
我成功地使用以下内容将前缀添加到stderr
输出。
command 2>&1 | sed "s/^/[prefix] /"
但是这只会将结果发送到stdout
。
如何在将行拖到前一个输出(保留stdout和stderr)时为command
的任何输出添加前缀?
答案 0 :(得分:1)
您只能使用shell管道语法来管道stdout。如果要分别处理stdout和stderr,则需要两个管道。命名管道可以在这里工作。
以下是演示解决方案的示例脚本
#!/bin/bash
PREF="$1"
shift
NPOUT=pipe.out
NPERR=pipe.err
mkfifo $NPOUT $NPERR
# Make two background sed processes
sed "s/^/$PREF/" <$NPOUT &
sed "s/^/$PREF/" <$NPERR >&2 &
# Run the program
"$@" >$NPOUT 2>$NPERR
rm $NPOUT $NPERR
用法:
./foo.sh "[prefix] " command -options
它将使用其stdin提供command
并将command
的stdout和stderr分别发送到它的stdout和stderr。
注意我没有压制sed
的stderr,这可能会干扰输出。你可以这样做:
sed "s/^/$PREF/" <$NPOUT 2>/dev/null &
^^^^^^^^^^^
答案 1 :(得分:0)
作为iBug答案以及this和especially this答案的组合,我想出了一个使用临时文件描述符的单行程序:
command 1> >(sed "s/^/[prefix]/") 2> >(sed "s/^/[prefix]/" >&2)
或作为一项功能:
function prefix_cmd {
local PREF="${1//\//\\/}" # replace / with \/
shift
local CMD=("$@")
${CMD[@]} 1> >(sed "s/^/${PREF}/") 2> >(sed "s/^/${PREF}/" 1>&2)
}
prefix_cmd "prefix" command