分享

Linux前世今生(三)Unix Shell

 苏醒的贝壳 2020-03-16

Shell是什么?它是怎么来的?

Linux前世今生(三)Unix Shell

好像几乎没有人能很清晰的解答这个问题。有人说,Shell(又被称为壳)是相对于Kernel(核)来说的。Kernel是操作系统的核心组件,它是操作系统程序的一部分,驻留在内存当中,处理应用程序与计算机硬件之间的交互。那么Shell就是计算机用户与应用程序之间的'一层物质“,当用户登录系统后,Shell也会驻留到内存当中,处理用户与应用程序之间的交互。因此,Shell会有”图形“Shell与”命令行”Shell之分。

这种说法,似乎有那么一些道理,但仔细想想,又会让人觉得迷糊。我们知道,很多情况下,用户直接与应用程序打交道就好了,何必多此一举在中间加一个“壳”呢?让我们回顾一下自己经常使用的应用软件,特别是具有图形交互界面的软件,有多少声称自己通过“xx壳”与用户进行交互呢?

所以,我们要弄明白“壳”到底是什么,需要回到一切的最开端--MULTICS。

至于MULTICS是什么,这里不再赘述。请查看本系列的头两篇文章。

在MULTICS的“博物馆网站”上,有一段对“壳”的描述

The Multics command processor used to be called the shell. This program is passed a command line for execution by the listener; it parses the line into a command name and arguments, locates the command and initiates it, and calls the command program with arguments that are PL/I character strings. It is simple to replace the default system supplied shell with a user-provided program, by calling cu_$set_cp (see abbrev).

简单翻译如下:

MULTICS的命令处理器曾经被称作“Shell”。它本身是一个程序。侦听器(另外一个程序)把命令行发送给Shell程序,随后该程序将命令行拆解为”命令名“与”参数“。接着,它根据命令名找到对应要执行的程序,对被执行的程序进行初始化,然后将刚才解析出来的参数传给该程序并执行。由于Shell本身是个程序,所以它可以被任何用户自己开发的程序所代替。

Louis Pouzin(路易·普津)是最早提出“Shell”概念的人。作为MIT计算中心的专家,他于1963年左右在CTSS上开发了一个叫做“RUNCOM”的程序。他之所以开发RUNCOM,是因为他脑海中突然闪过的一个念头:“命令”是否应该模块化,调用命令是否能够像执行子程序那样简单?

据Louis Pouzin的叙述,由于种种原因,他并没有太多参与到MULTICS当中。但他仍然对“命令模块化”的理想念念不忘。Christopher Strachey -- 一位来自于英国的计算机科学牛人(克里斯·托弗,“虚拟化”概念的发明人),曾在MIT待过一段时间。在那期间,Christopher Strachey提出了一个“宏生成器”的概念。这大大启发了Louis Pouzin。后来,他提交了一篇论文,用于阐述在MULTICS应当如何实现“命令模块化”。在这篇论文当中,Louis Pouzin首次提出了“Shell”这个单词。

Linux前世今生(三)Unix Shell

当然,MULTICS并没有迎来爆发。它只是一个奠基者,所以他的很多创意都只是起到了“抛砖引玉”的作用,Shell也是如此。

在那之后,肯·汤普逊继承了MULTICS的衣钵,并一手缔造了Unix。同时,被他顺带手从MULTICS拿过来的,还有Shell。

肯·汤普逊的游戏瘾很大。

为了能够从PDP-7上运行自己从MULTICS上开发的Space Travel游戏(参考上本系列上一篇),肯·汤普逊在不到一个月的时间完成了操作系统的雏形,并用了将近一周的时间开发了操作系统的Kernel、文本编辑器、编译器,同时还移植了Shell。而这些都是基于PDP-7 的汇编语言实现的。

当然,这些并不能算是真正的Unix,同时肯·汤普逊开发的Shell也不能算是真正的Unix Shell,因为它只是在汤普逊的“玩具”PDP-7上开发实现的。

1971年,肯·汤普逊的团队发布了第一个“正式”的Shell版本--V6 shell,它也被后人称为“Thompson shell”。这个Shell是基于C实现的,它很精简,只有九百多行代码。在这个Shell版本中,第一次引入了”重定向“与”管道“(也就是<、<<、>、>>及|)。同时,还支持以分号(;)或”与“符号(&)分隔的命令序列。

Thompson shell的最大短板就是--它缺少脚本能力。它唯一能做到的事情就是执行命令并输出执行结果。

Thompson shell的继任者是Mashey shell(PWB shell)。它的作者是John Mashey。Mashey shell在Thompson shell的基础上扩展了脚本语言,并支持变量定义。它还内置了条件分支与循环控制。Mashey shell伴随Unix5发行,在Unix6中仍然作为Thompson shell的备选Shell。

对于“脚本”这个概念,也是挺让人模棱两可的。它到底是一种程序,还是一种编程语言呢?

在某百科上,对于脚本(script)是这样描述的:

A scripting or script language is a programming language for a special run-time environment that automates the execution of tasks[1]; the tasks could alternatively be executed one-by-one by a human operator. Scripting languages are often interpreted (rather than compiled).

简单翻译一下:

脚本或脚本语言是一种运行时环境下的编程语言。它的目的是批量执行自动化任务(当然这些任务也可以人为的一条一条的执行)。脚本语言通常是解释型的(而非编译型的)。

Primitives are usually the elementary tasks or API calls[clarification needed], and the language allows them to be combined into more programs. Environments that can be automated through scripting include software applications, web pages within a web browser, usage of the shells of operating systems (OS), embedded systems, as well as numerous games. A scripting language can be viewed as a domain-specific language for a particular environment; in the case of scripting an application, it is also known as an extension language.

脚本的行为通常包括一些基本的管理任务或API调用。脚本语言可以将这些管理任务或API进行组合,形成完整的(自动化)程序。通常来说,应用程序、网页、浏览器、支持Shell的操作系统、嵌入式系统、还有各种各样的游戏..都可以通过脚本实现一些运行时的自动化程序。脚本语言可以被认为是服务于特定环境并专注于特定业务领域的编程语言。在应用程序进行开发时,脚本也被认作是一种(服务于核心程序框架之外的)扩展语言。

基于上面的分析,脚本最核心的三个方面就是:批量、自动化、任务与API的组合。因此,脚本本质上是一种效率工具。有了这个工具,用户可以在不了解应用程序底层逻辑的情况下,实现一种更高维度的“应用程序扩展”或”自动化作业“。我们拿游戏来说,游戏程序本身的开发是一件非常繁琐的事情,包括游戏画面的展示、游戏与玩家的交互等。然而一旦游戏的基础框架被搭建起来之后,游戏的二次开发者们就可以通过“脚本”实现各种各样的游戏剧情,从而为游戏的玩家们带来各种各样新奇有趣的游戏体验。这是一种高效的“二次开发”过程。因为在这个过程中,游戏框架内部的复杂元素都被隐藏起来了。

让我们回到Shell的话题。在对“脚本”这个概念进行深入研究后,我们对“Mashey shell相较于Thompson shell有了怎样的提升”这件事上有了更加深刻的理解。有了脚本,有了逻辑分支,有了流程控制,运维人员和开发者们终于在不需要了解操作系统内部实现细节的情况下有了大展拳脚的机会。

此后,1979年由Stephen Bourne开发的Bourne shell横空出世,在1979年发行的Unix7中,取代了Mashey shell,坐上了Unix Shell的头把交椅。同时,它也把操作系统Shell带到了一个新的高度。

Bourne shell是在Mashey shell基础上开发的,并进行了很多重大改进,以至于它与我们今天常用的Bash Shell的差别已经不算大。

Stephen Bourne是一个无聊的英国老头儿,除了学术方面造诣颇深之外,他在职业或学业生涯当中实在没有什么趣谈。

Linux前世今生(三)Unix Shell

在这里,我们把Bourne shell的一些主要特性罗列如下。限于作者的耐性,这里就不一一翻译了。

Scripts can be invoked as commands by using their filename (脚本可通过文件名调用)

May be used interactively or non-interactively(支持交互式或非交互式)

Allows both synchronous and asynchronous execution of commands(同步与异步)

Supports input and output redirection and pipelines(输入输出重定向)

Provides a set of built-in commands(一些内置命令)

Provides flow control constructs, quotation facilities, and functions.(脚本的流程控制、引用与函数)

Typeless variables(无类型变量)

Provides local and global variable scope(本地及全局变量)

Scripts do not require compilation before execution(脚本执行前不需要预编译)

Does not have a goto facility, so code restructuring may be necessary(不支持goto)

Command substitution using back quotes: `command`.(单引号执行命令)

Here documents using << to embed a block of input text within a script.(通过<<包裹一段文本)

'for ~ do ~ done' loops, in particular the use of $* to loop over arguments, as well as 'for ~ in ~ do ~ done' loops for iterating over lists.(支持for循环)

'case ~ in ~ esac' selection mechanism, primarily intended to assist argument parsing.(支持case分支)

sh provided support for environment variables using keyword parameters and exportable variables.(支持环境变量)

Contains strong provisions for controlling input and output and in its expression matching facilities.

Built-in test command – System III shell (1981)

# as comment character – System III shell (1981)

Colon in parameter substitutions '${parameter:=word}' – System III shell (1981)

continue with argument – System III shell (1981)

cat <<-EOF for indented here documents – System III shell (1981)

Functions and the return builtin – SVR2 shell (1984)

Built-ins unset, echo, type – SVR2 shell (1984)

Source code de-ALGOL68-ized – SVR2 shell (1984)

Modern '$@' – SVR3 shell (1986)

Built-in getopts – SVR3 shell (1986)

Cleaned up parameter handling allows recursively callable functions – SVR3 shell (1986)

8-bit clean – SVR3 shell (1986)

Job control – SVR4 shell (1989)

Multi-byte support – SVR4 shell (1989)

从Bourne shell开始,Shell“市场”开始了百家争鸣时代。这里面包括Korn shell(ksh)、Almquist shell (ash)以及最著名的Bourne Again Shell (or Bash)。一个比较个别的shell产品是C shell (csh),它让Shell的脚本看上去更像用C语言编写。下图是Shell的族谱。

Linux前世今生(三)Unix Shell

参考资料

https://www./mgs.html

https://developer.ibm.com/technologies/linux/tutorials/l-linux-shells/#artrelatedtopics

http:///lc3_adv_othershells.php


Linux前世今生(三)Unix Shell

运维就是服务的创造者和维护者!

IT运维之眼-“诸葛运帷” 业务级运维监控管理平台,企业端到移动端的运维监控整体解决方案。系统以业务系统监控为主线,基于“业务、软件、网络、设备、动环”多个监控视角的运维体系架构,打造了一个多维度可视化的综合运维监控管理平台。系统以故障提前预警、问题快速定位为核心。切实保障信息系统的安全稳定运行。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多