免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1482 | 回复: 3
打印 上一主题 下一主题

C shell:评估Linux中的shell [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-16 17:54 |只看该作者 |倒序浏览
Bourne shell 有两个主要目标:用作一个命令解释器来交互式执行操作系统命令,以及用于编写脚本(编写可通过 shell 调用的可重用脚本)。 除了取代 Thompson shell,Bourne shell 还提供了相对于其前身的多项优势。Bourne 向脚本中引入了控制流、循环和变量,提供了一种更加强大的语言来与操作系统交互(包括交互式和非交互式)。该 shell 还允许您使用 shell 脚本作为过滤器,提供对处理信号的集成支持,但缺乏定义函数的能力。 最后,它整合了我们如今使用的许多功能,包括命令替换(使用反引号)和用于将保留的字符串文字嵌入到脚本中的 HERE 文档。

Bourne shell 不仅是向前发展的重要一步,也是众多衍生的 shell 的基础,其中许多 shell 如今应用在典型的 Linux 系统中。图 1 演示了重要 shell 的系列。Bourne shell 导致了 Korn shell (ksh)、Almquist shell (ash) 和流行的 Bourne Again Shell(或 Bash)的开发。在 Bourne shell 发布时,C shell (csh) 正在开发。图 1 显示了主要系列,但没有展示所有影响,也没有展示一些具有重要贡献的 shell。


图 1. 1977 年以来的 Linux shell


我们稍后将分析其中一些 shell,查看为它们的进步做出贡献的语言和功能示例。

基本 shell 架构

一种假想的 shell 的基本架构很简单(Bourne 的 shell 就是一个证据)。在图 2 中可以看到,基本架构看起来类似一个管道,其中会分析和解析输入,展开符号(使用各种方法,比如括号、波浪号、变量、参数扩展和替换,以及文件名生成),最终执行命令(使用 shell 内置的命令或外部命令)。


图 2. 假想 shell 的简单架构


在 参考资料 部分中,您可以找到一些链接来了解开源 Bash shell 的架构。

探索 Linux shell

现在让我们看看其中一些 shell,回顾它们所做的贡献并在每个 shell 中查看示例脚本。查看的内容包括 C shell、Korn shell 和 Bash。

Tenex C shell

C shell 是 Bill Joy 1978 年在加州大学伯克利分校攻读研究生期间为 Berkeley SoftwareDistribution (BSD) UNIX 系统开发的。5 年后,该 shell 引入了来自 Tenex 系统(在 DEC PDP 系统上很流行)的功能。Tenex 引入了文件名和命令完成功能,以及命令行编辑功能。Tenex C shell (tcsh) 仍然向后兼容 csh,但改进了它的整体交互式功能。tcsh 是 Ken Greer 在 Carnegie Mellon University 开发的。

该 C shell 的一个重要的设计目标是创建一种类似 C 语言的脚本语言。这是一个有用的目标,因为 C 语言是所使用的主要语言(此外,该操作系统也是主要使用 C 语言开发的)。

Bill Joy 在 C shell 中引用的一项有用功能是命令历史。此功能维护以前执行的命令的历史,允许用户检查并轻松选择之前的命令来执行。例如,键入命令 history 将显示以前执行的命令。可使用向上和向下箭头来选择命令,或者可以使用 !! 执行前一个命令。也可以引用以前的命令的参数,例如 !* 引用前一个命令的所有参数,其中 !$ 引用前一个命令的最后一个参数。

看一下 tcsh 脚本的一个简单示例(清单 1)。这段脚本获取一个参数(一个目录名称),输出该目录中的所有可执行文件以及找到的文件数量。我将在每个示例中重用此脚本设计来演示区别。

tcsh 脚本可分解为 3 个基本部分。首先,请注意,我使用了 shebang 或 hashbang 符号来将此文件声明为可由定义的 shell 可执行文件(在本例中为 tcsh 二进制文件)解释。这允许我以常规可执行文件的形式执行该文件,而不在它之前添加解释器二进制文件。它维护找到的可执行文件数量,所以我将此数量初始化为 0。


清单 1. 用 tcsh 编写的查找所有可执行文件的脚本

#!/bin/tcsh
# find all executables

set count=0

# Test arguments
if ($#argv != 1) then
  echo "Usage is $0 <dir>"
  exit 1
endif

# Ensure argument is a directory
if (! -d  $1) then
  echo "$1 is not a directory."
  exit 1
endif

# Iterate the directory, emit executable files
foreach filename ($1/*)
  if (-x $filename) then
    echo $filename
    @ count = $count + 1
  endif
end

echo
echo "$count executable files found."

exit 0


第一部分测试用户传递的参数。#argv 变量表示传入的参数数量(不包括命令名称本身)。您可指定这些参数的索引来访问它们:例如,#1 表示第一个参数(它是 argv[1] 的简写)。该脚本需要一个参数;如果它未找到该参数,则输出一条错误消息,使用 $0 表示在控制台输入的命令名称(argv[0])。

第二部分确保传入的参数是一个目录。如果该参数是一个目录,-d 操作符返回 True。但请注意,我首先指定了一个 ! 符号,这表示无效。这样,表达式可表明,如果参数不是一个目录,则输出一条错误消息。

最后一部分迭代目录中的文件,以测试它们是否可执行文件。我使用方便的 foreach 迭代器,它循环括号(在本例中为该目录)中的每一项,然后在循环中测试每一项。这一步使用 -x 操作符测试文件是否为可执行文件,如果是,则输出该文件并将数量加一。在脚本的末尾,我输出可执行文件的数量。

Korn shell

Korn shell (ksh) 由 David Korn 设计,是在与 Tenex C shell 相同的时期引入的。Korn shell 的一项最有趣的功能是,它除了向后兼容原始的 Bourne shell,还可用作脚本语言。

Korn shell 在 2000 年以开源形式发布(依据 Common Public License)以前一直是专用的软件。除了提供与 Bourne shell 强大的向后兼容性,Korn shell 还包含其他 shell 的功能(比如 csh 的历史功能)。该 shell 还提供了可在现代脚本语言(比如 Ruby 和 Python)中找到的一些更加高级的功能 — 例如,关联数组和浮点算法。Korn shell 可用于多种操作系统,包括 IBM&reg; AIX&reg; 和 HP-UX,致力于支持 Portable Operating System Interface for UNIX (POSIX) shell 语言标准。

Korn shell 是 Bourne shell 的衍生物,因此看上去更像 Bourne shell 和 Bash 而不是 C shell。让我们看一个查找可执行文件的 Korn shell 示例(清单 2)。


清单 2. 用 ksh 编写的查找所有可执行文件的脚本

#!/usr/bin/ksh
# find all executables

count=0

# Test arguments
if [ $# -ne 1 ] ; then
  echo "Usage is $0 <dir>"
  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&reg;、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 <dir>"
  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。这个列表通过迭代指定的目录并在其中过滤是可执行文件的文件来生成。


清单 4. 用 scsh 编写的查找所有可执行文件的脚本

#!/usr/bin/scsh -s
!#

(define argc
        (length command-line-arguments))

(define (write-ln x)
        (display x) (newline))

(define (showfiles dir)
        (for-each write-ln
                (with-cwd dir
                        (filter file-executable? (directory-files "." #t)))))

(if (not (= argc 1))
        (write-ln "Usage is fae.scsh dir")
        (showfiles (argv 1)))


结束语

早期 shell 的许多理念和大量接口在之后的 35 年几乎未变 — 这是对早期 shell 的原始作者的贡献的有力证明。在一个不断自我改造的行业中,shell 已大大改进,但没有发生重大变化。尽管存在过创建特殊 shell 的尝试,但 Bourne shell 的衍生物仍然是所使用的主要 shell。

论坛徽章:
33
ChinaUnix元老
日期:2015-02-02 08:55:39CU十四周年纪念徽章
日期:2019-08-20 08:30:3720周年集字徽章-周	
日期:2020-10-28 14:13:3020周年集字徽章-20	
日期:2020-10-28 14:04:3019周年集字徽章-CU
日期:2019-09-08 23:26:2519周年集字徽章-19
日期:2019-08-27 13:31:262016科比退役纪念章
日期:2022-04-24 14:33:24
2 [报告]
发表于 2012-02-16 20:47 |只看该作者
bash用的越来越多了

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
3 [报告]
发表于 2012-02-16 20:51 |只看该作者
用户最多的应该是bash吧。

论坛徽章:
0
4 [报告]
发表于 2012-02-17 00:46 |只看该作者
很喜欢tcsh,但脚本还是bash给力啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP