在 shell 下区分 stdout 和 stderr 的两种思路

2009-08-07

1.使用命名管道重定向。在一个终端中新建命名管道,将标准错误重定向到此管道文件;在另一个终端中读取管道输出:

linjian@goslin:~/dev/outerr$ cat ./test1.sh
#!/bin/bash

while true; do
    echo "Input: "
    read FOO
    echo "I am in stdout, $FOO"
    echo "I am in stderr, $FOO" >&2
done
linjian@goslin:~/dev/outerr$ mkfifo mypipe
linjian@goslin:~/dev/outerr$ ./test1.sh 2> ./mypipe
Input:
Hello World
I am in stdout, Hello World
Input:

linjian@goslin:~/dev/outerr$ cat ./mypipe
I am in stderr, Hello World

也可以使用 Emacs 等在同一屏内显示两个终端。

2.使用匿名管道处理标准输出。由于标准错误不会进入管道,因此不会被管道后面的程序处理。例如使用“tr”来改变标准输出的大小写。

linjian@goslin:~/dev/outerr$ ./test1.sh | tr [a-z] [A-Z]
INPUT:
Hello World
I am in stderr, Hello World
I AM IN STDOUT, HELLO WORLD
INPUT:

想要更明显一点的话,可以用 ANSI 颜色特性,自己写一个简单的过滤器:

linjian@goslin:~/dev/outerr$ cat color.sh
#!/bin/bash

while true; do
    read FOO
    echo -e "\E[33;44m$FOO\E[37;40m"
done

或者直接使用像 ansi-color 这样的现成工具。