我正在使用2>&1 | MyFunction
这很有效。但是,我很难确定如何确定STDOUT
中传递的变量是STDERR
还是MyFunction
例如:
function MyFunction {
while read line; do
read IN
echo "LOG: $IN" >> $LOG_FILE;
done
}
如果它是STDOUT
或STDERR
的实例,是否有某种方法可以对传递的变量执行检查,以便我可以根据它执行条件规则?
答案 0 :(得分:2)
管道将传送标准输出(STDOUT)数据。
2>&1
将标准错误(“2”)重定向到文件描述符“1”,这是标准输出。
这意味着以下行:
myCommand 2>&1 | MyFunction
可以读作“运行myCommand,将标准错误重定向到标准输出,并在输出上运行MyFunction(这是标准错误+标准输出)”
一旦你写了2>&1
,就无法知道哪条线最初发送到STDOUT或STDERR。
答案 1 :(得分:1)
不直接,不。如果你不需要与Bash之外的其他shell兼容,你可以在Bash中使用一些技巧来为每一行添加前缀;例如
bash$ { perl -le 'print "oops"; die' 2> >(sed 's/^/stderr: /') > >(sed 's/^/stdout: /'); } 2>&1 | nl
1 stdout: oops
2 stderr: Died at -e line 1.
如您所见,两个sed
进程的输出重新组合为标准输出,然后通过管道传输作为行编号程序nl
的标准输入。大括号将命令分组,以便最终重定向2>&1
不会直接影响Perl进程。
答案 2 :(得分:1)
您可以使用:
# call the function like:
# cmd | log err
# cmd | log info
log() {
type="${1}"
while read -r line ; do
if [ "${type}" = "err" ] ; then
echo "EE ${line}"
else
echo "II ${line}"
fi
done
}
# Check this: https://stackoverflow.com/a/9113604/171318
# Use another file descriptor to separate between stdout and stderr
{ stdbuf -eL -oL cmd 2>&3 | log info ; } 3>&1 1>&2 | log err
# PS: ^ stdbuf makes sure that lines in output are in order