一、为什么要学习 Shell 编程 ?
1)Linux运维工程师在进行服务器集群管理时,需要编写Shell程序来进行服务器管理。
2)对于 JavaEE 和 Python 程序员来说,工作的需要,要求你编写一些 Shell脚本进行程序或者是服务器的维护,比如编写一个定时备份数据库的脚本。
3) 对于大数据程序员来说,需要编写Shell程序来管理集群。
二、Shell 使用场景(Shell 是什么,)
①、Shell 是什么
由于安全、复杂、繁琐等原因,用户不能直接接触内核(也没有必要),需另外再开发一个程序让用户直接使用这个程序;该程序作用就是接收用户操作(点击图标、输入命令)并进行简单处理,然后再传递给内核,这样用户就能间接地使用操作系统内核了。在用户和内核之间加一层“代理”,既能简化操作又能保障内核安全。
这个另外开发的程序就是这层“代理”。Linux下这个命令行程序叫 Shell。是一个应用程序,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。Shell 本身并不是内核的一部分,它只是站在内核基础上编写的一个应用程序,和 QQ、迅雷、Firefox 等其它软件没有什么区别。然而 Shell 也有着它的特殊性就是开机立马启动;用户通过 Shell 来使用 Linux,不启动 Shell 的话用户就没办法使用 Linux。
②、Shell 如何连接用户和内核?
Shell 程序本身功能是很弱的,比如文件操作、输入输出、进程管理等都得依赖内核。运行一个命令,大部分情况下 Shell 会去调用内核暴露出来的接口,这就是在使用内核,只是这个过程被 Shell 隐藏了起来,它自己在背后默默进行看不到而已。
接口其实就是一个个函数,使用内核就是调用这些函数。这就是使用内核全部内容了吗?嗯,是的!除了函数,没有别的途径使用内核。比如Shell 中输入cat log.txt
命令就可以查看 log.txt 文件中的内容,然而log.txt 放在磁盘的哪个位置?分成了几个数据块?在哪里开始?在哪里终止?如何操作探头读取它?这些底层细节 Shell 统统不知道的,它只能去调用内核提供的 open() 和 read() 函数,告诉内核我要读取 log.txt 文件,然后内核就按照 Shell 的吩咐去读取文件了,并将读取到的文件内容交给 Shell,最后由 Shell 呈现给用户(其实呈现到显示器上还得依赖内核)。整个过程 Shell 就是一个“中间商”,它在用户和内核之间“倒卖”数据。
三、Shell 连接其它程序
Shell 中输入的命令,有一部分是 Shell 本身自带的叫做内置命令;有一部分是其它应用程序(一个程序就是一个命令)这叫做外部命令。Shell 本身支持的命令并不多功能也有限,但 Shell 可以调用其他程序,每个程序就是一个命令,使得 Shell 命令数量可以无限扩展,结果就是 Shell 功能非常强大,完全能够胜任 Linux 日常管理工作,如文本或字符串检索、文件的查找或创建、大规模软件自动部署、更改系统设置、监控服务器性能、发送报警邮件、抓取网页内容、压缩文件等。更加惊讶的是,Shell 还可以让多个外部程序发生连接,在它们之间很方便地传递数据,就是把一个程序的输出结果传递给另一个程序作为输入。Shell 强大,并不是 Shell 本身功能丰富,而是它擅长使用和组织其他的程序。可以将 Shell 在整个 Linux 系统中的地位描述成下图所示的样子。注意“用户”和“其它应用程序”是通过虚线连接的,因为用户启动 Linux 后直接面对的是 Shell,通过 Shell 才能运行其它的应用程序。
四、Shell 编程(Shell 是一种脚本语言)
Shell 并不是简单的堆砌命令,我们还可以在 Shell 中编程,这和使用 C++、C#、Java、Python 等常见的编程语言并没有什么两样。Shell 虽然没有 C++、Java、Python 等强大,但也支持了基本的编程元素,例如:
- if...else 选择结构,case...in 开关语句,for、while、until 循环;
- 变量、数组、字符串、注释、加减乘除、逻辑运算等概念;
- 函数,包括用户自定义的函数和内置函数(例如 printf、export、eval 等)。
站在这个角度讲,Shell 也是一种编程语言,它的编译器(解释器)是 Shell 这个程序。我们平时所说的 Shell,有时候是指连接用户和内核的这个程序,有时候又是指 Shell 编程。Shell 主要用来开发一些实用的、自动化的小工具,而不是用来开发具有复杂业务逻辑的中大型软件,例如检测计算机的硬件参数、搭建 Web 运行环境、日志分析等,Shell 都非常合适。
尤其是 Linux 运维工程师,Shell 更是必不可少的,是必须掌握的技能,它使得我们能够自动化地管理服务器集群,否则你就得一个一个地登录所有的服务器,对每一台服务器都进行相同的设置,而这些服务器可能有成百上千之多,会浪费大量的时间在重复性的工作上。
五、常见的 Shell
常见的 Shell 有 sh、bash、csh、tcsh、ash 等。
sh
sh 的全称是 Bourne shell,由 AT&T 公司的 Steve Bourne开发,为了纪念他,就用他的名字命名了。sh 是 UNIX 上的标准 shell,很多 UNIX 版本都配有 sh。sh 是第一个流行的 Shell。
csh
sh 之后另一个广为流传的 shell 是由柏克莱大学的 Bill Joy 设计的,这个 shell 的语法有点类似C语言,所以才得名为 C shell ,简称为 csh。Bill Joy 是一个风云人物,他创立了 BSD 操作系统,开发了 vi 编辑器,还是 Sun 公司的创始人之一。
BSD 是 UNIX 的一个重要分支,后人在此基础上发展出了很多现代的操作系统,最著名的有 FreeBSD、OpenBSD 和 NetBSD,就连 Mac OS X 在很大程度上也基于BSD。
tcsh
tcsh 是 csh 的增强版,加入了命令补全功能,提供了更加强大的语法支持。
ash
一个简单的轻量级的 Shell,占用资源少,适合运行于低内存环境,但是与下面讲到的 bash shell 完全兼容。
bash
bash shell 是 Linux 的默认 shell。bash 由 GNU 组织开发,保持了对 sh shell 的兼容性,是各种 Linux 发行版默认配置的 shell。
bash 兼容 sh 意味着,针对 sh 编写的 Shell 代码可以不加修改地在 bash 中运行。
尽管如此,bash 和 sh 还是有一些不同之处:
- 一方面,bash 扩展了一些命令和参数;
- 另一方面,bash 并不完全和 sh 兼容,它们有些行为并不一致,但在大多数企业运维的情况下区别不大,特殊场景可以使用 bash 代替 sh。
六、Shell 脚本的执行方式
脚本格式要求
1)脚本以#!/bin/bash开头
2)脚本需要有可执行权限
方式1(输入脚本的绝对路径或相对路径)
说明:首先要赋予helloworld.sh 脚本的+x权限, 再执行脚本
比如/hello.sh 或者使用绝对路径/root/shcode/hello.sh
方式2(sh+脚本)
说明:不用赋予脚本+x权限,直接执行即可。
比如 shhello.sh,也可以使用绝对路径
七、编写第一个Shell 脚本
创建一个 Shell 脚本,输出hello world!
vim hello.sh
#!/bin/bash
echo "hello,world~"