Linux Shell 脚本快速入门
shell
脚本是在一个文件中写入一起执行的命令集。对于使用像dos操作系统的 DOS,windows操作系统的 bat,linux操作系统的 files 的人来说,这几乎都是相同的概念。你只需要把一串命令写入一个 text
文件然后一起运行。区别在于bash脚本比批处理文件能做的更多。
“ shell脚本是一种计算机程序,旨在由Unix shell(命令行解释器)运行。使用shell运行脚本的各种语言被认为是脚本语言。Shell脚本执行的典型操作包括文件操作,程序执行和打印文本。”
Unix操作系统有多种shell,使用它们中的任何一个编写脚本都可以写成一个专题,打包成一本书。在这篇文章中,我将介绍 bash脚本 的基本元素。
我要学吗?
心里坦承,使用 shell script 可以完成系统上的任何任务。当然,您也可以使用其他编程语言,诸如,Ruby,Python 或 Go 完成一些更多是单一或其编程语言擅长完成的小任务。无论如何,您将发现一定会用到 Shell Scripts 。
Shell scripts 经常用于系统运维自动化任务,装配复杂系统配置,优化系统性能等系统级配置场景。它突出的能力在于让多个 shell 命令有逻辑性地组合在一起,将需要多个命令才能完成的复杂的任务逻辑封装到一个脚本文件里形成一个命令。因此,提升了系统的灵活性、特殊性及使用价值。更进一步,shell 命令行和图形桌面运行环境的结合,不是矛盾,而是双赢。
- 自动化系统每日常规任务
- 创建自己系统独特的 shell 命令,可选创建与用户交互的命令。
- 体量小,易传播。mac 苹果系统和 Linux 系统基本通用。
编写Shell脚本
让我们从一个 Hello World 示例开始。打开您喜欢的编辑器并编写一个名为 my_script.sh 的shell脚本文件。包含以下行
#!/bin/bash
echo "hello world" //屏幕输出
第一行被称作 hashbang 或 shebang。 它告诉 Unix 这个脚本应该通过 /bin/bash shell 运行。第二行是 echo 语句,它将后面的单词打印到终端。
在保存了上面的文件之后,我们需要给它执行权限,使它可以运行。您可以按如下方式设置执行权限。
chmod +x my_script.sh //添加执行权限
可用通过下面的任意一个命令来执行脚本
$ bash my_script.sh
$ ./my_script.sh
样例输出
Hello world
现在我们已经完成了将 Hello world
打印到屏幕上的非常基本的 shell 脚本。
在我们深入研究 shell 脚本的一些语言结构之前,您应该对 Linux 命令有一些基本的了解。你可以在网上找到几篇相关的文章。下面是一篇示例文章,展示了一些常用的方法。
深入
现在我们已经了解了如何编写一个基本的 Hello World 示例,接下来让我们看看您在编写 shell 脚本时经常使用的一些语言结构。
变量
为了处理数据,数据必须保存在计算机的内存中。内存被划分为小的单元,每个单元都有一个唯一的编号,称为内存地址,用于存储数据
程序员可以为这个称为变量的内存地址提供唯一的名称。命名为存储位置的变量区域,该区域可以取不同的值,但每次只能取一个值。
在 Linux Shell 脚本中,有两种类型的变量:
- 系统变量——由Linux本身创建和维护。这种类型的变量用大写字母定义。
- 用户定义的变量——由用户创建和维护。这种类型的变量用小写字母定义。
可以在脚本中使用系统变量来显示这些变量包含的任何信息。像一些重要的系统变量:
- BASH — 保存 shell 名称
- BASH_VERSION — 保存 shell 版本名称
- HOME — 保存主目录路径
- OSTYPE — 保存操作系统类型
- USERNAME – 保存当前登录到计算机的用户名
注意 — 上面的一些系统变量在不同的环境中可能有不同的值.
用户自定义的变量与其他编程语言中的变量一样简单,但是变量可以存储任何类型的数据,如下面的示例所示:
# 定义变量的语法
name=abc
要访问用户自定义的变量,请使用以下语法:
#访问变量的语法
$name
屏幕输出:
#打印变量的语法
echo $name#输出
abc
在字符串中使用上面的变量:
#打印变量的语法
echo "My name is $name"#输出
My name is abc
引号
下面是 Shell 脚本中可用的三种引号。
双引号("): 除了 \ 和 $ 外,双引号内的任何内容都是字符串。看下面例子:
#定义字符串变量双引号的语法
str="Shell scripting article"
echo $str#输出
Shell scripting article#使用 \ 来转义字符
str="Shell scripting \"article\""
echo $str#输出
Shell scripting "article"#在字符串中使用变量
user="ABC"
str="Shell scripting \"article\" by $user"
echo $str#输出
Shell scripting "article" by ABC
单引号('):单引号内的任何内容都是字符串。 看下面例子:
#使用单引号定义字符串变量的语法
str='Shell scripting article'
echo $str#输出
Shell scripting article#尝试在单引号中使用 \ 转义字符
str='Shell scripting \"article\"'
echo $str#输出
Shell scripting \"article\"
左引号 (`): 左引号内的任何内容都将被视为可执行命令。 看下面例子:
#定义字符串变量的语法
str='Current date is `date`'
echo $str#输出
Current date is Wed Apr 4 10:57:12 +04 2018
条件 [if/else]
Shell 脚本使用相当标准的 if 语句的语法。条件语句使用 test 命令或命令执行。
if 语句最基本的形式是:
# 简单的 if then 语句的语法
if [ 35 -gt 0 ]
then
echo "Greater"
fi# 输出
Greater
你注意到 fi 的拼写是 if 倒过来的吗?参见下面包含 else 语句的示例:
#简单的 if then 语句的语法
if [ 35 -gt 45 ]
then
echo "Greater"
else
echo "Lesser"
fi#输出
Lesser
使用 elif 命令添加 else-if 语句结构。
# 简单 if then else-if 语句的语法
if [ 35 -gt 55 ]
then
echo "Greater"
elif [ 35 -gt 45 ]
then
echo "Greater"
else
echo "Lesser"
fi# Output
Lesser
条件语句在 Shell 脚本中有许多不同的使用方法。下表详细说明了如何添加一些重要的比较:
字符串比较
+------------------+-----------------------------------------------+
| 条件 | 描述 |
+------------------+-----------------------------------------------+
| Str1 = Str2 | 如果字符串相等,则为真 |
| Str1 != Str2 | 如果字符串不相等,则为真 |
| -n Str1 | 如果字符串不为空,则为真 |
| -z Str1 | 如果字符串为空,则为真 |
+------------------+-----------------------------------------------+
数值比较
+------------------+-----------------------------------------------+
| 条件 | 描述 |
+------------------+-----------------------------------------------+
| expr1 -eq expr2 | 如果表达式相等,则为真 |
| expr1 -ne expr2 | 如果表达式不相等,则为真 |
| expr1 -gt expr2 | 如果表达式1大于表达式2,则为真 |
| expr1 -ge expr2 | 如果表达式1大于等于表达式2,则为真 |
| expr1 -lt expr2 | 如果表达式1小于表达式2,则为真 |
| expr1 -le expr2 | 如果表达式1小于等于表达式2,则为真 |
| !expr1 | 否定表达式的结果 |
+------------------+-----------------------------------------------+
这就是 shell 脚本中条件的基本用法。
循环
几乎所有的语言都有循环的概念,如果我们想要重复一个任务十次,我们不想要输入代码十次,每次可能会有一点变化。
因此,我们在 shell 脚本中有 for
和 while
循环。这比其他语言的特性要少一些。
For 循环:
# 简单的 for 循环语句
for i in 1 2 3 4 5
do
echo "Hello world $i"
done#输出
Hello world 1
Hello world 2
Hello world 3
Hello world 4
Hello world 5
上面的 for 循环首先创建变量 i,并从 1 到 5 的数字列表中给它分配一个数字,shell 对 i 的每次分配执行 echo语句,在每次 迭代 中,它将回显输出中所示的语句。这个过程将持续到最后一项。
While 循环
While循环将一直执行,直到条件为真。看下面的例子:
# 简单的 While 循环语句
i = 1
while [ $i -le 5 ]
do
echo "Hello world $i"
i=`expr $i + 1`
done# 输出
Hello world 1
Hello world 2
Hello world 3
Hello world 4
Hello world 5
上面的脚本首先创建一个值为 1 的变量 i。然后循环迭代直到 i 的值小于等于 5。语句
i=expr $i + 1
负责 i 的增值。
如果这个语句被删除,上面所说的循环将是一个 无限循环。
函数
函数( Function)是一种程序或处理过程类型。它封装了一个任务(逻辑组合了多个指令去完成确定的工作)并形成一条指令(一个供调用的函数名)。许多程序( programming) 语言本身提供许多内建的 函数(functions)。若没有这些函数,程序中要需要许多指令语句去完成某项任务。例如,计算一个数的平方。
在 shell 脚本中,有两种方式定义函数。
- 在本脚本文件里定义函数并调用。
- 创建单独的脚本文件包含供其他脚本调用的函数定义。例如, library.sh 文件里包含所有用到的函数。
在脚本文件中定义和使用函数,见下面的示例:
#声明和定义简单函数的语法
print_date()
{
echo "Today is `date +"%A %d %B %Y (%r)"`"
return
}
#调用上面定义的函数
print_date
#程序输出
Today is Thursday 05 April 2018 (12:11:23 PM)
脚本退出状态
exit 指令终止脚本的执行。类似 C 语言程序的 exit 指令语句。它返回一个数值到创建脚本子进程的父进程。
shell 中每执行完成一个命令,这条命令都返回一个表示 退出状态(exit status) 的数值(常常也被称做 'return status' 或 'exit code' )。一条正确执行完成的命令返回 0 值,否则,返回非零值,这个值被称作 error code 。它可能对应到一个简单的文字解释说明错误原因。设计优良的 UNIX 命令,程序和工具软件,在出现一些非致命异常的情况下也能完成执行并返回 0。
当一个 shell 脚本内部执行无参数的 exit 指令时,脚本的退出状态是脚本里执行 exit 指令前最后一个执行的命令的退出状态。
#exit 语法
LAST_COMMAND
# 将会以 LAST_COMMAND 执行的退出状态为脚本的退出状态返回
exit 指令与 exit $? 完全相同,只写成 exit 即可。
LAST_COMMAND
# LAST_COMMAND 执行完成后,返回值会保存在 $? 变量中,脚本以这个值返回
$? 在 shell 里是个特殊的变量,每当一个命令完成后,它返回的退出状态值都保存在变量 $? 中。当前 shell 状态下,$? 里保存的是最后完成命令的返回状态值。
到这里,本文已近尾声。 现在,关于外壳脚本( Shell scripts )我希望您已得到个基础梗概的了解。若您有任何问题或反馈,请发到留言区。深入阅读 了不起的 Shell 和 GNU 的官方 bash 参考.
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: