对话 UNIX: !$#@*%( 二 )


清单 2. 把进程列表重定向到 grep
# ps –ef | grep –E "rpc|ksh"
root 196718 1516740 11:00:27 - 0:00 /usr/sbin/rpc.mountd
 daemon 225402 1516740 11:00:27 - 0:00 /usr/sbin/rpc.statd
root 229498 1516740 11:00:27 - 0:00 /usr/sbin/rpc.lockd
root 340144 1680180 12:34:56 - 0:00 rpc.ttdbserver 100083 1
cormany 409708 5695220 19:29:27 pts/1 0:00 -ksh
cormany 733202 4097080 19:52:20 pts/1 0:00 grep -E rpc|ksh
当多次把 stdout 重定向到 stdin 时,管道的使用方法可以很复杂 。在下面的示例中,扩展了前面的 ps 和 grep 示例,把它的 stdout 重定向到另一个 grep,其作用是排除包含 “grep 或 “ttdbserver 的字符串 。当最后的 grep 操作完成时,再次使用管道把 stdout 重定向到一个 awk 语句,其作用是输出进程标识符(PID)大于 200,000 的所有进程:
# ps –ef | grep –E "rpc|ksh" | grep -vE "grep|rpc.ttdbserver" |
awk -v _MAX_PID=200000 '{if ($2 > _MAX_PID) {print "PID for
process",$8,"is greater than", _MAX_PID}}'
PID for process /usr/sbin/rpc.statd is greater than 200000
PID for process /usr/sbin/rpc.lockd is greater than 200000
PID for process -ksh is greater than 200000
图 1 通过图形说明命令的 stdout 重定向到后续命令的 stdin 的次序 。
图 1. 管道示例
用 >、>>、< 和 << 执行数据重定向
通过命令行界面(CLI)执行命令的另一个重要方面是,能够把各种输出写到一个设备,或者把来自另一个设备的输入读取到命令中 。要想写一个命令的输出,需要在执行的命令后面加上大于号(> 或 >>)和所需的目标文件名或设备 。如果目标文件不存在,而且您对目标目录有写权限,那么 > 和 >> 会创建这个文件并根据您的 umask 设置权限,然后把命令的输出写到刚创建的文件中 。但是,如果这个文件存在,> 会尝试打开文件并覆盖整个内容 。如果希望在这个文件中追加内容,那么只需使用 >> 。可以认为它的作用是把左边命令的输出数据流移动到右边的目标文件中(即 -> -> ) 。
下面的示例执行 “管道 一节中的 ps –ef 示例,并把输出重定向到文件 ps_out:
# ps –ef | grep –E "rpc|ksh" > ps_out
下面的代码执行前面扩展的管道示例并把输出重定向到同一个文件(ps_out),但是追加到当前数据后面:
# ps –ef | grep –E "rpc|ksh" | grep -vE "grep|rpc.ttdbserver" |
awk -v _MAX_PID=200000 '{if ($2 > _MAX_PID) {print "PID for
process",$8,"is greater than", _MAX_PID}}' >> ps_out
清单 3 给出前两个重定向的输出 。
清单 3. 重定向的输出
# cat ps_out
root 196718 1516740 11:00:27 - 0:00 /usr/sbin/rpc.mountd
 daemon 225402 1516740 11:00:27 - 0:00 /usr/sbin/rpc.statd
root 229498 1516740 11:00:27 - 0:00 /usr/sbin/rpc.lockd
root 340144 1680180 12:34:56 - 0:00 rpc.ttdbserver 100083 1
cormany 409708 5695220 19:29:27 pts/1 0:00 -ksh
cormany 733202 4097080 19:52:20 pts/1 0:00 grep -E rpc|ksh
PID for process /usr/sbin/rpc.statd is greater than 200000
PID for process /usr/sbin/rpc.lockd is greater than 200000
PID for process -ksh is greater than 200000
当只使用 > 重定向输出时,只重定向命令的 stdout 。但是,除了 stdout,还有 stderr 输出:前者表示为 1,后者表示为 2 。在 Unix 中输出重定向没有区别 。只需在 > 前面加上所需的输出类型(例如,1>、2>),告诉 shell 要把输出路由到哪里 。
清单 4 尝试列出 fileA.tar.bz2 和 fileC.tar.bz2 。但是,如第一个命令(ls)所示,fileC.tar.bz2 不存在 。好在可以把 stdout 和 stderr 分别重定向到 ls.out 和 ls.err,这样就能够看到错误消息 。

推荐阅读