Shell

简介

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。

单独地学习 Shell 是没有意义的,Shell 需要依赖其他程序才能完成大部分的工作,这或许是它的缺陷,但它不容置疑的长处是:简洁的脚本语言标记方式,而且比 C 语言编写的程序执行更快、更有效率。

换句话说,Shell 基本没有语法难度,但是它更多用的是对应工具的管理命令。比如:写个 LAMP 安装脚本,你重点需要熟悉是 LAMP 的工具管理命令,而不是简单地 shell 语言。

目前主要学习 shell 的基础和简单应用,后面学习了足够的管理工具,再深入应用。

图形界面和命令行要达到的目的是一样的,都是让用户控制计算机。

Shell 除了能解释用户输入的命令,将它传递给内核,还可以: 1. 调用其他程序,给其他程序传递数据或参数,并获取程序的处理结果; 2. 在多个程序之间传递数据,把一个程序的输出作为另一个程序的输入; 3. Shell 本身也可以被其他程序调用。

由此可见,Shell 是将内核、程序和用户连接了起来。

Shell 能做什么

  1. 自动化系统初始化(Update, 软件源配置、更新、时区设置、安全策略) 当我们装完系统之后,我们需要对系统的时区、软件包的源、软件更新、安全设置等进行一些初始化

    我怎么没想到呢 emm,早知道早点学 shell 了,苦了我重装了那么多次系统。

  2. 自动化批量软件部署程序(LAMP/LNMP/Tomcat/LVS/Nginx)

  3. 自动化管理程序(例如:KVM-manager 管理、集群管理扩容、MySQL,DELLR720 批量管理 RAID)

  4. 日志分析处理程序(网站统计数据 PV、UV 处理过滤,如:top 100 等,常用 grep/awk)

  5. 自动化备份恢复程序(MySQL 完全备份/增量备份 + Crond)

  6. 自动化管理程序(批量远程修改密码、软件升级、配置更新)

  7. 自动化信息采集及监控程序(收集系统/应用程序状态、CPU、Mem、Disk、Net、TCP Status、Apache、MySQL)

  8. 配合 Zabbix 信息采集(收集系统/应用状态信息,CPU、Mem、Disk、Net、TCP Status、Apache、MySQL)

  9. 自动化扩容(根据峰值访问动态调整云主机个数 --> 业务上线) Zabbix 监控 CPU 80% -> 预处理: 通过亚马逊、阿里云等提供的 Python API 调用增加(删除) AWS/EC2 等云主机 -> Shell Script(对新增的云主机进行业务上线)

  10. 俄罗斯方块、打印三角形、打印圣诞树、打印五角星、运行小火车、坦克、排序算法

  11. Shell 理论上可以做任何事情(一切取决于业务需求) 当然,实际应用中,如果一个功能太过于复杂,也不建议使用 shell, 可以使用 Python,Go 等

语法规范

  1. shell 脚本的后缀一般为 .sh

  2. 命令正常执行返回值为 0,返回值为 ? 变量,我们可以用 $? 来获取它的值

  3. 分号; 作为不同命令的分隔

  4. &&|| 的短路作用,可以进行逻辑判断,达到 if 判断真假的作用,比如: ping -c 1 www.baidu.com &>/dev/null && echo "www.baidu.com is up" || echo "www.baidu.com is down"

Python Shell 执行方式对比

程序

著名的瑞士计算机科学家、PASCAL 语言发明者 N·沃思(Niklaus Wirth)教授提出程序定义的著名公式:程序=算法+数据结构 以上公式说明了如下两个问题: (1)算法决定如何构造和组织数据(算法 → 数据结构)。 (2)算法的选择依赖于作为基础的数据结构(数据结构 → 算法)。

算法是数据操作,数据结构是数据的描述

简单对比

  1. Shell 解释性脚本,可以直接在 shell 中以交互模式运行 当然,shell 有多种(而且都有些差异),但一般就指 bash

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ cat /etc/shells
    # Pathnames of valid login shells.
    # See shells(5) for details.

    /bin/sh
    /bin/bash
    /bin/zsh
    /usr/bin/zsh
    /usr/bin/git-shell

  2. Python

    1. 解释 Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
    2. 编译 Python 源码 --> Python 的 byte code(.pyc 格式) --> Python Virtual Machine 执行 和 Java 或 .NET 相比,Python 的 Virtual Machine 距离真实机器的距离更远。或者可以说 Python 的 Virtual Machine 是一种抽象层次更高的 Virtual Machine。基于 C 的 Python 编译出的字节码文件,通常是.pyc 格式
  3. 一个有趣的现象:在 Java 写好网站之后,每个功能点第一次点击都比较慢,因为第一次点击的时候需要将其编译成字节码,以后就快了

shebang

  1. 通过 $! 开始一个脚本, It is called a shebang or a "bang" line. #! 后面跟着解释器的绝对路径,例如:#!/usr/bin/bash
  2. shebang 只能第一行,也只有放在第一个行有效,放在非第一行,那就只是注释了。
  3. Linux 上所有的脚本执行都会使用第一行的 shebang 指定的解释器。
  4. 这确保即使即使脚本在其他 shell 在中执行时候,也会使用 shebang 指定的解释器 常见的 shebang: #!/bin/bash#!/usr/bin/perl#!/usr/bin/python#!/usr/bin/python3#!/usr/bin/env bas
  5. 显式指定解释器时,则使用显式的,不显示指定,默认使用 shebang 指定的。 隐式执行 shell 脚本,不写 shebang,影响不太大,而 python 之类脚本的,在 shell 中隐式执行,,如果没有 shebang 的话,则会使用 bash/shell 作为解释器。 不同类型脚本,在 shebang 中指定对应的解释器。

推荐写法:

You should use #!/usr/bin/env bash for portability: different *nixes put bash in different places, and using /usr/bin/env is a workaround to run the first bash found on the PATH. And sh is not bash.

通过 which 可以查看解释器的路径,此外,我们还可以看到 sh 其实是指向 bash 的一个软链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# violetv at manjaro in ~/testsh [13:58:37]
$ which python
/usr/bin/python

# violetv at manjaro in ~/testsh [13:58:44]
$ which sh
/usr/bin/sh

# violetv at manjaro in ~/testsh [13:58:49]
$ which bash
/usr/bin/bash

$ ll /usr/bin/bash
-rwxr-xr-x 1 root root 907K 5月 27 03:32 /usr/bin/bash

# violetv at manjaro in ~ [13:03:03]
$ ll /usr/bin/sh
lrwxrwxrwx 1 root root 4 5月 27 03:32 /usr/bin/sh -> bash

扩展阅读

如何清楚易懂的解释“UV 和 PV"的定义?

参考资料

Linux Shell 脚本自动化编程实战(完整版)

What is the preferred Bash shebang?

Shebang

Python