对话 UNIX: 掌握强大的命令行( 三 )


但是,如果您打算使用 bash 来处理多个文件,该怎么办呢?cat file1 file2 file3 | bash 是一种可行的方法,这也许也是唯一的一种方法,因为在 bash 中并不支持如 bash < file1 < file2 < file3 的语法 。
而且,bash 无法将输出重定向到多个目标 。例如,您可从 bash 命令行中输入指令 bighairyscript > ~/log | mail -s "Important stuff" team 。
但在相对较新的 shell 如 Z shell(zsh;请参阅参考资料)中,可以在同一命令行内处理多个输入和输出 。例如,使用以下命令可将 stdout 保存到名为 log 的文件中并通过电子邮件发送给您自己:
清单 6. Z shell
zsh% bash < tellme > log | mail -s "Who you are" 'whoami'
bash: line 4: systemname: command not found
zsh% Your current login, working Directory, and system are...
strike
/home/strike
(短语 “whoami运行命令 whoami 并将该命令的结果插入到短语所在位置 。它类似于在运行命令行的其他部分之前先运行一条短小 shell 命令 。)
现在我们对上一条命令从左向右进行分析 。bash 命令创建文件 log 并将在 tellme 文件中找到的命令的 stdout 发送给您自己 。由于 stderr 没有通过 > 或管道进行定向,因此错误消息将被打印到 stdout 。命令 file 等同于 cat > file 。)
Z shell 还可处理多个输入重定向 。Z shell 命令行 cat < file1 < file2 < file3 等同于 cat file1 file2 file3 。显然,原有语法较后者更加繁琐,总的来说,多个 stdout 重定向要更加常用的多 。但是,如果您要运行的实用工具不接受多个输入参数,则可使用 Z shell 的多个输入重定向 。
Z shell 中还具有其他新特性,包括更好的 globbing(通配符匹配)、先进的模式匹配和扩展的命令自动完成系统,从而减少您在命令行中的字符输入 。本系列中的后续两篇文章将进一步探讨 Z shell 。
Shell 技巧
通过一些功能强大的命令行组合,能明显提高您的工作效率 。这些命令可以在所有的 shell 中工作,而不仅仅是 zsh 。
使用 tar 为任何目录创建包括符号链接在内的完整副本:
tar cf - /path/to/original | 
 (mkdir -p /path/to/copy; cd /path/to/copy; tar xvf -)
第一个 tar 命令将目录 /path/to/original 进行归档并将归档文件写到 stdout,创建 (c) 选项后面使用的连字符 (-) 表示 stdout 。括号中的命令为一个 subshell:subshell 中的命令不会影响当前 shell 的环境 。mkdir -p 创建指定目录,包括任何需要创建的中间目录;cd 命令则切换到新目录 。第二个 tar 命令从 stdin 读取归档文件并进行展开,展开 (x) 选项后面使用的连字号表示 stdin 。
要在保存命令序列的 stdout 同时进行查看,可使用 less -O file。-O 选项会将 stdin 复制到指定的 file 中 。如下例所示:
sort /etc/aliases | less -Osorted
如果目录中包含数千个文件,则您的 shell(包括 zsh,取决于文件数目及其名称)可能无法使用通配符匹配来列举出所有文件,因为命令行通常具有一定的字符数限制 。因此,类似以下 shell 脚本:
foreach i (*)
...
end
可能会执行失败 。(当超出允许命令行长度时,您可能看到类似 Line length exceeded 的消息 。)如果出现此类错误,可使用管道 xargs 实用工具 。xargs 命令可从管道中读取数据并为每行读取内容运行指定命令 。
例如,如果您要查找服务器上的所有引用 www.example.com 的网页,可使用以下命令行:
% find / -name '*HTML' -print
 | xargs grep -l 'www.example.com'
 | less -Opages
xargs 接收来自 find 的文件名并重复运行 grep -l 以处理每个文件,而不论有多少个文件 。(grep -l 在发现一个匹配项之后即打印文件的名称并停止在该文件中的进一步匹配 。) less 允许您对结果进行分页并将列表保存在文件指定页中 。命令结果为包含字符串“www.example.com的文件名列表 。

推荐阅读