坚持知识分享,该文章由Alopex编著, 转载请注明源地址: http://www.cnblogs.com/alopex/
索引:
- 什么是shell
- shell的分类
- shell脚本的执行方式
摘要:
- 了解shell的本质是什么
- 了解除bash这个shell之外,还有哪些shell
- shell 脚本以及shell脚本的执行方式/区别
什么是shell
一般来说,操作系统由用户接口(User Interface)和系统内核(kernel)两部分构成
从名字可以看出,内核是操作系统的核心, 它是一个操作系统的灵魂
内核的主要作用有以下几点
- 文件管理 (File manager) 协调调度计算机中的大容量存储
- 设备驱动 (Device drivers) 使接入计算机的周边设备能相互通信
- 内存管理 (Memory manager) 协调调度计算机中的内存
- 进程调度 (Scheduler) 协调调度系统中的进程
- 时间调度 (Dispatcher) 给予进程CPU的使用时间
- 系统调用 (System calls) 进程请求系统内核去执行一些它(普通进程)没有权限执行的命令
- 简单概括, 内核负责管理计算机硬件资源(CPU, 内存, 硬盘, 周边设备I/O)的使用
内核是如此的重要, 它对系统的稳定高效运行起到至关重要的作用.
因如此, 操作系统是不允许用户直接和内核进行交互的
它(OS)给予用户另外一个对操作系统访问的方式, 被称为用户接口(UI)
专门用于系统和用户进行交互
早期的计算机中,操作系统只有命令行界面(command-line interface) 简称为CLI
在英文单词中shell的中文翻译为 [壳] 表示的是用坚硬的东西保护保护内部柔软部分
用SHELL来描述命令行界面, 这个 "时髦"的说法 最早(1964 - 1965)诞生于 Multics 其中一位研发者Louis Pouzin
关于 SHELL 起源的故事, 可以点击这里浏览更多 http://www.multicians.org/shell.html
感谢Louis Pouzin 为CLI 赋予了一个形象生动的名字 : )
- 简单地概括, shell 本质应该是CLI, 它是一个让用户通过命令行来实现和系统交互的接口.
shell的分类
操作系统: CentOS release 6.9 (Final)
命令提示符 PS1 : \[\e[31m\]>\[\e[m\] (下图中红色的> 为命令提示符)
来介绍shell的分类之前, 先来介绍一下关于shell查看的几个常用操作
查看系统默认的shell
查看系统中拥有的shell
查看bash的版本
2014年9月, bash曾曝出一个严重的漏洞CVE-2014-6271
ShellShock Bug (特制环境变量注入攻击)
我们使用以下命令对系统进行测试
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
如果测试的结果只显示了 "this is a test" 表示你的系统正常, 否则你需要对bash打补丁 (以下仅针对CentOS/redhat)
Linux shell的大类有以下两种 Bourne shell 以及 C shell
首先介绍 Bourne shell
Bourne shell 家族中有三大成员, [sh, ksh, bash]
[SH]
sh 其的开发者是 Stephen Bourne.
它在 V7 Unix 中作为默认shell 替代了之前使用的 Thompson shell
有意思的是,sh设置sh的许多特性依然沿用至今
Features of the Bourne shell versions since 1979 include:
- 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)
[Ksh]
Ksh 全称是 KornShell , 其研发者是 David Korn
它最初的开发是基于Bourne shell的, 因此隶属于 Bourne shell的阵列中
与 sh相比, 它拥有以下的特性
- Job control, command aliasing, and command history designed after the corresponding C shell features. Job control was added to the Bourne Shell in 1989.
- A choice of three command line editing styles based on vi, Emacs, and XEmacs.
- Associative arrays and built-in floating point arithmeticoperations (only available in the ksh93 version of KornShell).
- Dynamic extensibility of built-in commands (as of ksh93)
[bash]
bash 的全称是 Bourne-again shell, 其开发则是GUN计划的 Brian Fox
目的是为了替代 Bourne shell
它是Linux众多发行版和apple (最早是 OSX) 默认的shell, 现如今微软Windows10也有对其的支持
虽然bash是用作sh的替代品, 但是bash并不能完全兼容sh, 这是需要注意的.
在CentOS 6.9 中, sh 是一个连接到 bash 上的连接文件, 因此使用sh 命令和 bash命令效果是一样的
C Shell 家族有两个成员 [csh, tcsh]
[csh]
csh 其设计者是 Bill Joy
由于csh拥有交互的特性, 在1980年, csh以其易于上手的特性, 赢得了青睐
csh的设计理念是使得它开起来更像是 C语言, 并且拥有更好的用户交互性
Bourne shell #!/bin/shif [ $days -gt 365 ]then |
C shell #!/bin/cshif ( $days > 365 ) then echo This is over a year.
endif
|
以上这个例子, 可以说明csh 与 bash 中脚本书写的差异性
就以上的脚本而言, csh的可读性略胜一筹
[tcsh]
由于sh有进阶版的bash, csh也有其进阶版,名字就叫tcsh
它是BSD 相关系统的tcsh
简单整理一下
shell 有两大阵型 Bourne shell 与 C shell
Bourne shell (sh) --> Korn shell (ksh)
Bourne shell (sh) --> Bourne again shell (bash) 总多Linux发行版上最流行的shell
csh --> tcsh 如今在BSD系统上最流行的shell
shell 脚本的执行方式
# 执行的脚本
[第一种方式 sh script.sh]
这是一种十分常用的 shell 脚本执行方式. 因为它不需要用户给予脚本执行权限
sh 命令接收 script.sh 这个文件作为传入参数, 开启一个子shell进行命令的解析与执行
[第二种方式 source(.) script.sh]
这种方式, 也不需要用户给予脚本执行权限, 脚本将直接在当前shell中执行
这意味着, 在script.sh 中定义的变量或函数, 在脚本执行结束后, 变量的值或函数返回值等将被保留
(需要注意的是, "." script.sh 这种方式只能在 bash 类型的shell中执行
而 source script.sh 既能在 bash类型 也能在 csh 类型的shell中执行)
[第三种方式 ./script.sh]
这种方式, 用户必须赋予脚本执行权限(chmod a+x script.sh)
才能运行脚本, 该方式也是通过子shell对命令进行解析与执行
[关于 子shell 和 父shell]
简单来说,子shell和父shell的关系有以两点
1.子shell 会复制 父shell的变量和函数, 就如同子女继承父母的基因一样,
2.子shell中设置的变量和函数只有子shell自己知道, 子shell无法改变父shell设定的变量和函数
脚本执行中, 如果使用 source / . 方式执行脚本, 命令会于当前shell中解析执行
下面用一个简单的脚本来体会一下, 当前shell中执行脚本, 和子shell执行脚本的取本
脚本内容
使用当前shell执行完cd命令后, 当前shell的目录发生了变化
使用子shell执行完cd命令后, 当前shell的目录并没有发生改变
------------------------------
参考资料:
// Computer Science: An Overview (12th Edition)
// Kernel (operating system)
// The Origin of the Shell
// Command-line interface
// Why was the word “shell” used to descibe a command-line interface?
// Bash specially-crafted environment variables code injection attack
// What is the ShellShock Bug? (September 2014)
// ShellShock Attack Demonstration
// Bourne shell
// KornShell
// Bash (Unix shell)
// C shell
// tcsh
// Different ways to execute a shell script