UNIX 高手的10 个习惯( 三 )


在 Subshell 中运行命令列表
使用括号将命令列表包括在单个组中 。这样做将在一个新的 Subshell 中运行命令,并允许您重定向或收集整组命令的输出,如以下示例所示:
清单 11. 好习惯 6 的示例:在 Subshell 中运行命令列表
~ $ ( cd tmp/a/b/c/ || mkdir -p tmp/a/b/c &&
> VAR=$PWD; cd ~; tar xvf -C $VAR archive.tar )
> | mailx admin -S "Archive contents"
在此示例中,该存档的内容将提取到 tmp/a/b/c/ 目录中,同时将分组命令的输出(包括所提取文件的列表)通过邮件发送到地址 admin 。
当您在命令列表中重新定义环境变量,并且您不希望将那些定义应用于当前 Shell 时,使用 Subshell 更可取 。
在当前 Shell 中运行命令列表
将命令列表用大括号 ({}) 括起来,以在当前 Shell 中运行 。确保在括号与实际命令之间包括空格,否则 Shell 可能无法正确解释括号 。此外,还要确保列表中的最后一个命令以分号结尾,如以下示例所示:
清单 12. 好习惯 6 的另一个示例:在当前 Shell 中运行命令列表
~ $ { cp ${VAR}a . && chown -R guest.guest a &&
> tar cvf newarchive.tar a; } | mailx admin -S "New archive"
在 find 之外使用 xargs
使用 xargs 工具作为筛选器,以充分利用从 find 命令挑选的输出 。find 运行通常提供与某些条件匹配的文件列表 。此列表被传递到 xargs 上,后者然后使用该文件列表作为参数来运行其他某些有用的命令,如以下示例所示:
清单 13. xargs 工具的经典用法示例
~ $ find some-file-criteria some-file-path |
> xargs some-great-command-that-needs-filename-arguments
然而,不要将 xargs 仅看作是 find 的辅助工具;它是一个未得到充分利用的工具之一,当您养成使用它的习惯时,将会希望进行所有试验,包括以下用法 。
传递空格分隔的列表
在最简单的调用形式中,xargs 就像一个筛选器,它接受一个列表(每个成员分别在单独的行上)作为输入 。该工具将那些成员放置在单个空格分隔的行上:
清单 14. xargs 工具产生的输出示例
~ $ xargs
a
b
c
Control-D
a b c
~ $
您可以发送通过 xargs 来输出文件名的任何工具的输出,以便为其他某些接受文件名作为参数的工具获得参数列表,如以下示例所示:
清单 15. xargs 工具的使用示例
~/tmp $ ls -1 | xargs
December_Report.pdf README a archive.tar mkdirhIEr.sh
~/tmp $ ls -1 | xargs file
December_Report.pdf: PDF document, version 1.3
README: ASCII text
a: Directory
archive.tar: POSIX tar archive
mkdirhier.sh: Bourne shell script text executable
~/tmp $
xargs 命令不只用于传递文件名 。您还可以在需要将文本筛选到单个行中的任何时候使用它:
清单 16. 好习惯 7 的示例:使用 xargs 工具来将文本筛选到单个行中
~/tmp $ ls -l | xargs
-rw-r--r-- 7 joe joe 12043 Jan 27 20:36 December_Report.pdf -rw-r--r-- 1
root root 238 Dec 03 08:19 README drwxr-xr-x 38 joe joe 354082 Nov 02
16:07 a -rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar -rwxr-xr-x 1
joe joe 3239 Sep 30 12:40 mkdirhier.sh
~/tmp $
谨慎使用 xargs
从技术上讲,使用 xargs 很少遇到麻烦 。缺省情况下,文件结束字符串是下划线 (_);如果将该字符作为单个输入参数来发送,则它之后的所有内容将被忽略 。为了防止这种情况发生,可以使用 -e 标志,它在不带参数的情况下完全禁用结束字符串 。
了解何时 grep 应该执行计数——何时应该绕过
避免通过管道将 grep 发送到 wc -l 来对输出行数计数 。grep 的 -c 选项提供了对与特定模式匹配的行的计数,并且一般要比通过管道发送到 wc 更快,如以下示例所示:

推荐阅读