命令输出的前缀

时间:2018-03-27 08:02:15

标签: bash command-line stdout stderr

this question我学习了如何为命令的每个输出添加前缀:

command | sed "s/^/[prefix] /"

但这只会为stdout中的每一行添加前缀 我成功地使用以下内容将前缀添加到stderr输出。

command 2>&1 | sed "s/^/[prefix] /"

但是这只会将结果发送到stdout

如何在将行拖到前一个输出(保留stdout和stderr)时为command的任何输出添加前缀?

2 个答案:

答案 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答案以及thisespecially 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