#!/usr/bin/ksh
# find all executables
count=0
# Test arguments
if [ $# -ne 1 ] ; then
echo "Usage is $0
exit 1
fi
# Ensure argument is a directory
if [ ! -d "$1" ] ; then
echo "$1 is not a directory."
exit 1
fi
# Iterate the directory, emit executable files
for filename in "$1"/*
do
if [ -x "$filename" ] ; then
echo $filename
count=$((count+1))
fi
done
echo
echo "$count executable files found."
exit 0
在清单 2 中,您将注意到的第一点是它与 清单 1 的相似性。在结构上,该脚本基本上是相同的,但在执行条件、表达式和迭代的方式上存在明显的区别。没有采用类似 C 的测试操作符,ksh 采用了典型的 Bourne 风格操作符(-eq、-ne 和 -lt 等)。
Korn shell 也有用一些与迭代相关的区别。在 Korn shell 中,使用了 for in 结构,使用命令替换来表示从命令 ls '$1/*(表示指定子目录的内容)的标准输出创建的文件列表。
除了上面定义的其他功能,Korn 还支持别名功能(用于将一个词替换为用户定义的字符串)。Korn 还有其他许多功能默认已禁用(比如文件名称完成),但可由用户启用。
Bourne-Again Shell
Bourne-Again Shell(或 Bash)是一个开源 GNU 项目,旨在取代 Bourne shell。Bash 由 Brian Fox 开发,已成为世上最流行的 shell 之一(出现在 Linux、Darwin、Windows®、Cygwin、Novell、Haiku 等系统中)。顾名思义,Bash 是 Bourne shell 的一个超集,大部分 Bourne 脚本都可原封不动地执行。
除了支持脚本的向后兼容性,Bash 还整合了来自 Korn 和 C shell 的功能。您将找到命令历史、命令行编辑、一个目录栈(pushd 和popd)、许多有用的环境变量和命令完成等。
Bash 继续在发展,拥有许多新功能,支持正则表达式(类似于 Perl)和关联数组。尽管其中一些功能可能在其他脚本语言中不存在,但可以编写兼容其他语言的脚本。对于这一点,清单 3 中所示的示例脚本等同于 Korn shell 脚本(来自 清单 2),除了 shebang 区别 (/bin/bash)。
清单 3. 用 Bash 编写的查找所有可执行文件的脚本
#!/bin/bash
# find all executables
count=0
# Test arguments
if [ $# -ne 1 ] ; then
echo "Usage is $0
exit 1
fi
# Ensure argument is a directory
if [ ! -d "$1" ] ; then
echo "$1 is not a directory."
exit 1
fi
# Iterate the directory, emit executable files
for filename in "$1"/*
do
if [ -x "$filename" ] ; then
echo $filename
count=$((count+1))
fi
done
echo
echo "$count executable files found."
exit 0
这些 shell 之间的一个关键区别是它们的发布所依据的许可。您可能已猜到,Bash 是在 GNU 项目中开发的,是依据 GPL 发布的,而 csh、tcsh、zsh、ash 和 scsh 都是依据 BSD 或一种类似 BSD 的许可来发布的。Korn shell 可依据 Common Public License 使用。
外来的 shell
对于大胆的开发人员,可基于您的需要或爱好使用替代的 shell。Scheme shell (scsh) 提供了一种使用 Scheme(Lisp 语言的一种衍生物)的脚本环境。Pyshell 是对创建使用 Python 语言的类似脚本的一次尝试。最后,对于嵌入式系统,可以使用 BusyBox,它将一个 shell 和所有命令合并到一个二进制文件中,以简化其分发和管理。
清单 4 给出了以 Scheme shell (scsh) 编写的查找所有可执行文件的脚本。这段脚本可能看起来很奇怪,但它实现了与我们目前所提供的脚本类似的功能。这段脚本包含 3 个函数,直接使用可执行代码(在末尾)来测试参数数量。这段脚本真正强大之处在showfiles 函数内,它迭代一个列表(在 with-cwd 后构造),在列表的每个元素后调用 write-ln。这个列表通过迭代指定的目录并在其中过滤是可执行文件的文件来生成。