更好地理解UNIX® 用户输入的这些“奇怪的” 字符。
学习如何在UNIX 中使用管道、重定向、操作符等特性。
现在,您已经在IBM® AIX® 上工作了一段时间了。
您已经学习了几个基本命令,能够在目录结构中移动、创建和修改文件、查看正在运行的进程以及管理用户和系统。
这很不错,但是您希望了解UNIX® 管理员输入的命令是什么意思。
这些命令中包含许多奇怪的符号。
在本文中,了解|、>、>>、<、<<、[[和]]等符号在UNIX 和Linux® 中的意思,以及如何使用&&、||、<、<=和!=操作符。
管道如果您熟悉UNIX,那么管道(或pipe)会是每天都要接触到的东西。
管道最初是由Malcolm McIlroy 开发的,可以使用管道把一个命令的标准输出(stdout)定向到下一个命令的标准输入(stdin),这样就形成了连续执行的命令链。
可以在一个命令行上使用多个管道。
在许多时候,一个命令的stdout 用作下一个命令的stdin,第二个命令的stdout 又被重定向到另一个命令的stdin,依此类推。
例如,在排除故障或执行日常检查时,大多数UNIX 管理员首先做的事情之一是查看系统上当前正在运行的进程。
清单1演示这样的检查。
清单 1. 日常进程检查示例# ps –efUID PID PPID C STIME TTY TIME CMDroot 1 0 0 Jul 27 - 0:05 /etc/initroot 53442 151674 0 Jul 27 - 0:00 /usr/sbin/syslogdroot 57426 1 0 Jul 27 - 0:00 /usr/lib/errdemonroot 61510 1 0 Jul 27 - 23:55 /usr/sbin/syncd 60root 65634 1 0 Jul 27 - 0:00 /usr/ccs/bin/shlap64root 82002 110652 0 Jul 27 - 0:24 /usr/lpp/X11/bin/X -x abx-x dbe -x GLX -D /usr/lib/X11//rgb -T -force :0 -auth /var/dt/A:0-SfIdMaroot 86102 1 0 Jul 27 - 0:00 /usr/lib/methods/ssa_daemon -l ssa0root 106538 151674 0 Jul 27 - 0:01 sendmail: accepting connectionsroot 110652 1 0 Jul 27 - 0:00 /usr/dt/bin/dtlogin -daemonroot 114754 118854 0 Jul 27 - 20:22 dtgreetroot 118854 110652 0 Jul 27 - 0:00 dtlogin <:0> -daemonroot 131088 1 0 Jul 27 - 0:07 /usr/atria/etc/lockmgr-a /var/adm/atria/almd -q 1024 -u 256 -f 256root 147584 1 0 Jul 27 - 0:01 /usr/sbin/cronroot 155816 151674 0 Jul 27 - 0:04 /usr/sbin/portmaproot 163968 151674 0 Jul 27 - 0:00 /usr/sbin/qdaemonroot 168018 151674 0 Jul 27 - 0:00 /usr/sbin/inetdroot 172116 151674 0 Jul 27 - 0:03 /usr/sbin/xntpdroot 180314 151674 0 Jul 27 - 0:19 /usr/sbin/snmpmibdroot 184414 151674 0 Jul 27 - 0:21 /usr/sbin/aixmibdroot 188512 151674 0 Jul 27 - 0:20 /usr/sbin/hostmibdroot 192608 151674 0 Jul 27 - 7:46 /usr/sbin/muxatmdroot 196718 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.mountdroot 200818 151674 0 Jul 27 - 0:00 /usr/sbin/biod 6root 213108 151674 0 Jul 27 - 0:00 /usr/sbin/nfsd 3891root 221304 245894 0 Jul 27 - 0:05 /bin/nsrexecddaemon 225402 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.statdroot 229498 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.lockdroot 241794 151674 0 Jul 27 - 0:51 /usr/lib/netsvc/yp/ypbindroot 245894 1 0 Jul 27 - 0:00 /bin/nsrexecdroot 253960 1 0 Jul 27 - 0:00 ./mflm_managerroot 274568 151674 0 Jul 27 - 0:00 /usr/sbin/sshd -Droot 282766 1 0 Jul 27 lft0 0:00 /usr/sbin/getty /dev/consoleroot 290958 1 0 Jul 27 - 0:00 /usr/lpp/diagnostics/bin/diagdroot 315646 151674 0 Jul 27 - 0:00 /usr/sbin/lpdroot 319664 1 0 Jul 27 - 0:00 /usr/atria/etc/albd_serverroot 340144 168018 0 12:34:56 - 0:00 rpc.ttdbserver 100083 1root 376846 168018 0 Jul 30 - 0:00 rlogindcormany 409708 569522 0 19:29:27 pts/1 0:00 -kshroot 569522 168018 0 19:29:26 - 0:00 rlogindcormany 733188 409708 3 19:30:34 pts/1 0:00 ps -efroot 749668 168018 0 Jul 30 - 0:00 rlogind系统上当前正在运行的进程的列表可能像清单1这么简单;但是,大多数生产系统运行的进程更多,这会使ps的输出更长。
为了把这个列表缩短到自己需要的范围,可以使用管道把ps –ef的标准输出重定向到grep,从而搜索自己真正希望看到的结果。
清单2把清单1产生的进程列表重定向到grep,搜索字符串“rpc” 和“ksh”。
清单 2. 把进程列表重定向到grep当多次把stdout 重定向到stdin 时,管道的使用方法可以很复杂。
在下面的示例中,扩展了前面的ps和grep示例,把它的stdout 重定向到另一个grep,其作用是排除包含“grep” 或“ttdbserver” 的字符串。
当最后的grep 操作完成时,再次使用管道把stdout 重定向到一个awk语句,其作用是输出进程标识符(PID)大于200,000 的所有进程:图 1通过图形说明命令的 stdout 重定向到后续命令的 stdin 的次序。
图 1. 管道示例用 >、>>、< 和 << 执行数据重定向通过命令行界面(CLI )执行命令的另一个重要方面是,能够把各种输出写到一个设备,或者把来自另一个设备的输入读取到命令中。
要想写一个命令的输出,需要在执行的命令后面加上大于号(> 或 >>)和所需的目标文件名或设备。
如果目标文件不存在,而且您对目标目录有写权限,那么 > 和 >> 会创建这个文件并根据您的 umask 设置权限,然后把命令的输出写到刚创建的文件中。
但是,如果这个文件存在,> 会尝试打开文件并覆盖整个内容。
如果希望在这个文件中追加内容,那么只需使用 >>。
可以认为它的作用是把左边命令的输出数据流移动到右边的目标文件中(即 <cmd> -> <output> -> <file>)。
下面的示例执行 “管道” 一节中的 ps –ef 示例,并把输出重定向到文件 ps_out :回页首下面的代码执行前面扩展的管道示例并把输出重定向到同一个文件(ps_out),但是追加到当前数据后面:清单3给出前两个重定向的输出。
清单 3. 重定向的输出当只使用>重定向输出时,只重定向命令的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,这样就能够看到错误消息。
清单 4. 列出文件fileA.tar.bz2 和fileC.tar.bz2在AIX 中,对stdout 和stderr 使用>和>>时应用相同的规则。
例如,以后的测试可以使用相同的输出文件,见清单5。
清单 5. 使用输出文件进行以后的测试有时候,可能需要把stdout 和stderr 写到同一个文件或设备。
这有两种方法。
第一种方法是把1>和2>重定向到同一个文件:第二个方法更简单更快速,有经验的UNIX 用户更喜欢采用这种方法:我们分解这个语句。
首先,执行ls fileA.tar.bz2 fileC.tar.bz2。
然后使用> ls.out把stdout 重定向到ls.out,使用2>&1把stderr 重定向到前面重定向的stdout(ls.out)。