Shell作为外围软件生态群其中一个非常重要的组件。它是操作系统最外层的接口,负责直接面向用户交互并提供内核服务,包括命令行接口(CLI)或图形界面接口(GUI)两种形式。以CLI为例,它提供一套命令规范,是一种解释性语言,将用户输入经过解释器(interpreter)输出使其转化成真正的系统调用,实现人机交互的功能。
命令结构和规范
Thompson Shell命令语言结构和规范的基础,其解释器具有跨平台的可移植性,并影响到了后来包括Bourne Shell在内的各种脚本语言设计实现。下面我们就以其中5个特性重温一些大家已经耳熟能详的命令规范,你也可以通过sh(1)手册查看原始资料。过滤器/管道线(filter/pipeline)。这绝对是要载入Unix史册的发明,创立者是Douglas McIlroy,Thompson Shell引入并实现了这个伟大的概念——一个或多个命令组成一根过滤器的链条,由’|'或’^'符号分隔。除最后一个命令之外,每个命令的标准输出都被作为下一个命令的标准输入。这样每个命令都作为一个独立的进程来运行,并通过管道与邻近的进程相连接。圆括弧内的命令序列整体上可以替代单个命令作为过滤器实现,比如用户可以输入”(A;B)|C”。
命令序列和后台进程。分号’;'指示多个命令序列化执行。’&’符号指示该命令在后台异步执行,使得前面的管道线不必等待其终止,仅仅报告一个进程id,这样用户以后可以通过kill命令与它通信。有益于进程管理。
I/O重定向。它利用了Unix设计上的一个重要特性——一切皆文件,用三个符号表示:”重定向输出,如果文件不存在则创建它,如果文件存在则截断它;’>>’追加模式重定向输出,如果文件不存在则创建它,如果文件存在则追加输出至末尾处。
通配符扩展(globbing)。通配符的概念源自于正则表达式,使得解释器智能地处理用户不完全输入,比如记不清文件名、一次性输入多个文件等。’?'匹配任意单一字符;’*'匹配任意字符串(包括空串);成对’['和']‘定义了字符集合一个类,可匹配方括号内任意成员,用’-'两端可指定一系列连续字符匹配范围。
参数传递。这里主要引入了位置参数和选项参数的概念:’$n’指示shell调用的第n个参数替代;还定义了两个选项参数’-t’和’-c’,前者用于交互,导致shell从标准输入中读入一行作为用户执行的系统命令,后者指示shell将附带的下一个参数作为命令执行(可正确处理换行符),是对’-t’的补充,特别是调用者已经读取了命令其中某些字符的情况下。如果不带选项参数则直接读取文件名。
注:
I/O重定向
Linux中的标准输入和输出有三种类型:stdin、stdout和stderr
0(stdin,标准输入)、1(stdout,标准输出)、2(stderr,标准错误输出),默认与keyboard、monitor有关;
stdout是指将结果输出到终端或屏幕,如cat test的命令结果就是标准输出
stderr是指执行命令发生错误时,输出到屏幕的信息。如执行cat test时,如果test文件不存在,则 系统出现的"cat: test: 没有该文件或目录"信息就是标准错误输出。
虽然stdout和stderr都是将信息输出到屏幕上,但是它们的意义不同,最大的原因就是重定向的方式 不同。
1. 输出重定向(>)
通过 >重定向符可以将结果重定向到其他地方,如ls > test,就可以将当前目录下的文件列表输出到 文件test中。
cat命令结合重定向,可以构建一个简单的文本编辑器。先输入命令cat > test
因为此时未提供cat命令的任何参数,此时光标会停留在下一行的开头等待输入,此时便可输入需要 记录的内容,输入完毕后安回车(否则最后一行数据不会保存),再按Ctrl+C或Ctrl+D就可以结束
文件的编辑,此时当前目录下就创建了一个叫test的文件。
2. 附加输出重定向(>>)
与>不同,>>会在原有内容后追加内容,而>会覆盖原内容
3. 输入重定向(<)
输入重定向将键盘或文件提供给命令来执行。如,cat < test,先将test传给cat作为标准输入文件, 然后才将test的内容输出到屏幕。
4. 附加输入重定向(<<)
附加输入重定向允许用户自定义一个字符串,系统在收到此字符串前,会持续将数据输入文件。这个 功能常用在电子邮件系统中。如:
loveyj@loveyj-laptop:~$ mail test@test.com << quit
> hello, ubuntu!
> quit ------输入quit后才结束编辑
>和&>最大的差别在于,命令执行发生错误是,>会将错误信息直接显示在屏幕上,但不记录到文件中而&>则不论命令执行是否正确,都不会将信息显示在屏幕上,而是直接记录到文件中。
如,程序员很多都会习惯将程序测试和调试时的信息(正常和错误)记录在文件中,以便日后修改参考
管道(Pipe)
管道最主要的功能是将程序的输出结果,直接定向到另一个程序当成输入数据。
如/etc目录下有很多文件,如果使用ls -al命令,没办法在同一页显示,不方便浏览第一页数据。此时可 利用管道,将ls -al命令产生的结果执行定向到less命令,然后就可以使用上下箭头来逐行浏览了》
ls -al /etc | less