主页 实验环境 学习Linux - Study Area CN

Shell Script 基本语法

在前面,我们学习了 Shell 的基本命令以及变量,还有使用 Vim 编辑文件。我们是时候把这些放到一起来学习 Shell Script 了。

说是 Shell Script,本质上就是一堆命令的组合,可以方便你干一些重复的事情,提高你的效率。如果你曾经学习过其它编程语言,或者是 Windows 的批处理文件,那么你在学习 Shell Script 时应该会简单很多。不过没有经验也不要紧,让我们一起接下来的学习吧!

Shell Script 文件的结构

在 Linux 上,Shell Script 一般的后缀名是 .sh。不过,你可以使用任何后缀(但是为了可读性最好不要这么做),也可以像可执行文件一样干脆不加任何后缀。

一个 Shell Script 的结构如下面所示:

#!/bin/bash

<这里可以写任意的命令>
<这里可以写任意的命令>
...

你可以在这里面写上许多行使用回车分隔的命令,这些命令会被按顺序执行。

Shell Script 的结构非常自由。其中,第一行被称为 shebang,以 #! 开头,可以指定运行这个程序的程序(即解释器)。常见的如 /bin/bash 就是我们正在讲的 Shell Script,还有 /bin/sh 也是一样(但是缺少部分功能)。Shebang 也可以不加,但是就不能直接用 ./你的sh文件 去执行了。

Shebang 的用处很多,可以指定一个文本文件的执行方式,可以使任意文本文件(例如 Python 和 Awk 脚本)具有可执行的能力,而 Windows 就只能靠后缀名区分。

执行 Shell Script

Shell Script 的执行也很简单:

bash 你的sh文件
./你的sh文件

然后你的所写的命令会被一条一条按顺序执行下去。

在执行 Shell Script 的时候,你执行的所有命令用户都无法直接看到,只能看到每行命令的输出。

注释

在 Shell Script 中,我们可以使用 # 来编写注释。这一行从 # 开始到这行结尾的内容都会被忽略。例如:

# 这是注释内容

ls # 这也是注释内容,前面的 ls 会被执行

为什么要编写注释?注释可以让其他人或者几个月后的你快速读懂你的 Shell Script 而不用一行一行理解。所有最好养成一个写注释的习惯 (事实上很多程序员都不愿写注释)

字符串

如果我们想要在 Bash 中定义一段文本,你可以直接输入,但是如果在文本中要出现分号这类的字符,那么我们就要使用引号了。

在 Bash 中,定义文本(字符串)有下面几种方式:

  • 双引号 "

    这个是最常用的一种方式。在双引号中,我们可以包含分号等字符,也可以正常包含各种变量。例如 echo "test ${var}" 会输出 test 1(假设 var=1)。

  • 单引号 '

    在单引号中,如果你尝试包含变量的话,你会发现变量会按照原样输出,不会被替换。例如 echo 'test ${var}' 会输出 test ${var}

如果想要在字符串里再包含单双引号?别担心,我们可以使用 \ 进行字符串“转义”,就是把 \ 和它后面的一个字符一块看成一个特殊字符。需要转义的有 $ 、单双引号和它本身(使用 \\)。

参数

另外,在 Shell Script 运行时可以向前面的 cp 等命令一样携带参数。

可以使用下面的方法获取:

$0        # 获取执行当前脚本的命令
$1 ~ $9   # 获取第 n 个参数(n 代表 $ 后的数字)
${10}     # 同上,但是超过第 10 个参数后需要使用大括号

运算

在 Shell 中,我们如何让 Bash 进行运算呢?我们可以使用 $[] 表达式。例如:

echo "$[1+1]"

会输出 2

在运算中,我们同样可以使用变量。在运算中,变量通常不需要使用大括号。

var=1
echo "$[$var+1]"

同样会输出 2

Bash 中括号支持常见的数学运算符号,也有一些其它的符号:

  • +
  • -
  • *
  • /
  • % 模运算,或者说取余
  • > >= < <= != 判断数字大小,满足返回 1,否则返回 0
  • & 与符号,如果两个都不是 0 或者空,那么返回第一个不是 0(空)的数
  • | 或符号,如果第一个不是 0 或者空,那么返回第一个,否则返回第二个

与和或符号的这种运算被称为“短路”,返回结果如果继续进行逻辑运算的话也可以当成 1 使用。

Bash 中,中括号的数学运算本质上是 expr 命令。

显示进度

前面说了,你执行的所有命令用户都无法直接看到。那么我们如何让用户知道脚本进行到哪了呢?答案实际上很简单,就是 echo。用户是可以看到命令的输出的。

例如:

echo "第一步"
echo "第二步"
echo "第三步"
echo "完成"

等待

sleep 命令可以实现让用户“等一会”的作用,在脚本中有时会用到。它的使用也非常简单。

sleep 5 # 等待 5 秒
sleep 0.5 # 等待 0.5 秒

sleep 后面也可以加上单位。可用的单位如下:

  • s
  • m 分钟
  • h 小时
  • d

如:

sleep 5m # 等待 5 分钟
sleep 1m 2s # 等待 62 秒

从终端输入内容

在 Shell Script 中,我们如何从终端输入内容呢?我们可以使用 read 命令。例如:

read var
echo "你输入的内容是:$var"

然后你就可以在终端输入内容了。

如果你希望它能在你输入时有提示,那么可以使用 -p 参数。例如:

read -p "请输入你的名字:" var
echo "你输入的内容是:$var"

如果你希望输入一个密码,让它输入的内容不显示在终端上,那么可以使用 -s 参数。例如:

read -s -p "请输入你的密码:" var
echo "你输入的内容是:$var"

小技巧:使用 read -s -N 1 可以实现“按任意字符继续”的功能。

课后作业

Bash 和 Shell Script 本身其实并不是很难,但是却有着无穷多的可能性。我们学习使用 Shell Script 可以方便我们的学习与工作。

尝试在所有 Shell Script 中写上完整的注释吧!

  1. 编写一个 helloworld.sh,可以输出 5 遍 Hello, World!
  2. 编写一个 write.sh,可以传入一个文件名参数,可以把 Hello, World! 写入到这个文件里。
  3. 编写一个 add.sh,可以从终端输入两个数字,可以输出这个两个数字的和。