要测试它,确认 ~/testdir 仍然是当前的工作目录(PWD)。删除目录下所有东西,来看下这个显式写出值列表的 for 循环的简单的示例。这个列表混合了字母和数字 — 但是不要忘了,在 bash 中所有的变量都是字符串或者可以被当成字符串来处理。
1 2 3 4 5 6 7 8 9 10
[student@studentvm1 testdir]$ rm * [student@studentvm1 testdir]$ for I in a b c d 1234 ; do echo $I ; done a b c d 1 2 3 4
给变量赋予更有意义的名字,变成前面版本的进阶版:
1 2 3 4 5 6 7 8
[student@studentvm1 testdir]$ for Dept in"Human Resources" Sales Finance "Information Technology" Engineering Administration Research ; doecho"Department $Dept" ; done Department Human Resources Department Sales Department Finance Department Information Technology Department Engineering Department Administration Department Research
创建几个目录(创建时显示一些处理信息):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
[student@studentvm1 testdir]$ for Dept in "Human Resources" Sales Finance "Information Technology" Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept" ; done Working on Department Human Resources Working on Department Sales Working on Department Finance Working on Department Information Technology Working on Department Engineering Working on Department Administration Working on Department Research [student@studentvm1 testdir]$ ll total 28 drwxrwxr-x 2 student student 4096 Apr 8 15:45 Administration drwxrwxr-x 2 student student 4096 Apr 8 15:45 Engineering drwxrwxr-x 2 student student 4096 Apr 8 15:45 Finance drwxrwxr-x 2 student student 4096 Apr 8 15:45 'Human Resources' drwxrwxr-x 2 student student 4096 Apr 8 15:45 'Information Technology' drwxrwxr-x 2 student student 4096 Apr 8 15:45 Research drwxrwxr-x 2 student student 4096 Apr 8 15:45 Sales
在 mkdir 语句中 $Dept 变量必须用引号包裹起来;否则名字中间有空格(如 Information Technology)会被当做两个独立的目录处理。我一直信奉的一条实践规则:所有的文件和目录都应该为一个单词(中间没有空格)。虽然大部分现代的操作系统可以处理名字中间有空格的情况,但是系统管理员需要花费额外的精力去确保脚本和 CLI 程序能正确处理这些特例。(即使它们很烦人,也务必考虑它们,因为你永远不知道将拥有哪些文件。)
再次删除 ~/testdir 下的所有东西 — 再运行一次下面的命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
[student@studentvm1 testdir]$ rm -rf * ; ll total 0 [student@studentvm1 testdir]$ for Dept in Human-Resources Sales Finance Information-Technology Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept" ; done Working on Department Human-Resources Working on Department Sales Working on Department Finance Working on Department Information-Technology Working on Department Engineering Working on Department Administration Working on Department Research [student@studentvm1 testdir]$ ll total 28 drwxrwxr-x 2 student student 4096 Apr 8 15:52 Administration drwxrwxr-x 2 student student 4096 Apr 8 15:52 Engineering drwxrwxr-x 2 student student 4096 Apr 8 15:52 Finance drwxrwxr-x 2 student student 4096 Apr 8 15:52 Human-Resources drwxrwxr-x 2 student student 4096 Apr 8 15:52 Information-Technology drwxrwxr-x 2 student student 4096 Apr 8 15:52 Research drwxrwxr-x 2 student student 4096 Apr 8 15:52 Sales
假设现在有个需求,需要列出一台 Linux 机器上所有的 RPM 包并对每个包附上简短的描述。我为北卡罗来纳州工作的时候,曾经遇到过这种需求。由于当时开源尚未得到州政府的“批准”,而且我只在台式机上使用 Linux,对技术一窍不通的老板(PHB)需要我列出我计算机上安装的所有软件,以便他们可以“批准”一个特例。
[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary" Name : a2ps Summary : Converts text and other types of files to PostScript Name : aajohan-comfortaa-fonts Summary : Modern style truetypefont Name : abattis-cantarell-fonts Summary : Humanist sans serif font Name : abiword Summary : Word processing program Name : abrt Summary : Automatic bug detection and reporting tool <snip>
在上面的命令中你可以试试用 grep 代替 egrep ,你会发现用 grep 不能得到正确的结果。你也可以通过管道把命令结果用 less 过滤器来查看。最终命令像这样:
1
[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary" > RPM-summary.txt
这个命令行程序用到了管道、重定向和 for 循环,这些全都在一行中。它把你的 CLI 程序的结果重定向到了一个文件,这个文件可以在邮件中使用或在其他地方作为输入使用。