1.使用多个命令
shell脚本的关键在于输入多个命令并处理每个命令的结果,甚至需要将一个命令的结果传给另一个命令。shell可以让你将多个命令串起来,一次执行完成。如果要两个命令一起运行,可以把它们放在同一行中,彼此间用分号隔开。
[root@jerry ~]# date ; who
Thu Dec 6 23:52:40 CST 2018
root pts/0 2018-12-06 17:49 (192.168.181.1)
这个简单的脚本只用到了两个bash shell命令。 date 命令先运行,显示了当前日期和时间,后面紧跟着 who 命令的输出,显示当前是谁登录到了系统上。
2.创建shell脚本文件
在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。其格式为:
#!/bin/bash
在通常的shell脚本中,井号( # )用作注释行。shell并不会处理shell脚本中的注释行。然而,shell脚本文件的第一行是个例外, # 后面的惊叹号会告诉shell用哪个shell来运行脚本(是的,你可以使用bash shell,同时还可以使用另一个shell来运行你的脚本)。在指定了shell之后,就可以在文件的每一行中输入命令,然后加一个回车符。之前提到过,注释可用 # 添加。例如:
#!/bin/bash
# This script displays the date and who's logged on
date
who
还有,要注意另有一行也以 # 开头,并添加了一个注释。shell不会解释以 # 开头的行(除了以#! 开头的第一行)。留下注释来说明脚本做了什么,这种方法非常好。
要让shell找到某个脚本,只需采取以下两种作法之一:
将shell脚本文件所处的目录添加到 PATH 环境变量中;
在提示符中用绝对或相对文件路径来引用shell脚本文件。
chmod 命令赋予文件属主执行文件的权限。
3.显示消息
大多数shell命令都会产生自己的输出,这些输出会显示在脚本所运行的控制台显示器上。很多时候,你可能想要添加自己的文本消息来告诉脚本用户脚本正在做什么。可以通过 echo 命令来实现这一点。
4 使用变量
运行shell脚本中的单个命令自然有用,但这有其自身的限制。通常你会需要在shell命令使用其他数据来处理信息。这可以通过变量来实现。变量允许你临时性地将信息存储在shell脚本中,以便和脚本中的其他命令一起使用。
4.1 环境变量
shell维护着一组环境变量,用来记录特定的系统信息。比如系统的名称、登录到系统上的用户名、用户的系统ID(也称为UID)、用户的默认主目录以及shell查找程序的搜索路径。可以用set 命令来显示一份完整的当前环境变量列表。
4.2 用户变量
除了环境变量,shell脚本还允许在脚本中定义和使用自己的变量。定义变量允许临时存储数据并在整个脚本中使用,从而使shell脚本看起来更像一个真正的计算机程序。
用户变量可以是任何由字母、数字或下划线组成的文本字符串,长度不超过20个。用户变量区分大小写,所以变量 Var1 和变量 var1 是不同的。
使用等号将值赋给用户变量。在变量、等号和值之间不能出现空格(另一个困扰初学者的用法)。
4.3 命令替换
shell脚本中最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量。把输出赋给变量之后,就可以随意在脚本中使用了。这个特性在处理脚本数据时尤为方便。
有两种方法可以将命令输出赋给变量:
反引号字符( ` )
$() 格式
命令替换允许你将shell命令的输出赋给变量。
5 重定向输入和输出
有些时候你想要保存某个命令的输出而不仅仅只是让它显示在显示器上。bash shell提供了几个操作符,可以将命令的输出重定向到另一个位置(比如文件)。重定向可以用于输入,也可以用于输出,可以将文件重定向到命令输入。
5.1 输出重定向
最基本的重定向将命令的输出发送到一个文件中。bash shell用大于号(>)来完成这项功能:
command > outputfile
之前显示器上出现的命令输出会被保存到指定的输出文件中。
将命令的输出追加到已有文件中,比如你正在创建一个记录系统上某个操作的日志文件。在这种情况下,可以用双大于号(>>)来追加数据。
5.2 输入重定向
输入重定向和输出重定向正好相反。输入重定向将文件的内容重定向到命令,而非将命令的输出重定向到文件。
输入重定向符号是小于号(<):
command < inputfile
一个简单的记忆方法就是:在命令行上,命令总是在左侧,而重定向符号“指向”数据流动的方向。小于号说明数据正在从输入文件流向命令。
还有另外一种输入重定向的方法,称为内联输入重定向(inline input redirection)。这种方法无需使用文件进行重定向,只需要在命令行中指定用于输入重定向的数据就可以了。
内联输入重定向符号是远小于号(<<)。除了这个符号,你必须指定一个文本标记来划分输入数据的开始和结尾。任何字符串都可作为文本标记,但在数据的开始和结尾文本标记必须一致。
6 管道
有时需要将一个命令的输出作为另一个命令的输入。
将其直接重定向到另一个命令。这个过程叫作管道连接(piping)。
和命令替换所用的反引号(`)一样,管道符号在shell编程之外也很少用到。该符号由两个竖线构成,一个在另一个上面。然而管道符号的印刷体通常看起来更像是单个竖线(|)。在美式
键盘上,它通常和反斜线(\)位于同一个键。管道被放在命令之间,将一个命令的输出重定向到另一个命令中:
command1 | command2
不要以为由管道串起的两个命令会依次执行。Linux系统实际上会同时运行这两个命令,在系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区。
7 执行数学运算
另一个对任何编程语言都很重要的特性是操作数字的能力。遗憾的是,对shell脚本来说,这个处理过程会比较麻烦。在shell脚本中有两种途径来进行数学运算。
7.1 expr 命令
最开始,Bourne shell提供了一个特别的命令用来处理数学表达式。 expr 命令允许在命令行上处理数学表达式,但是特别笨拙。
$ expr 1 + 5
6
7.2 使用方括号
bash shell为了保持跟Bourne shell的兼容而包含了 expr 命令,但它同样也提供了一种更简单的方法来执行数学表达式。在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和
方括号( $[ operation ] )将数学表达式围起来。
8 退出脚本
迄今为止所有的示例脚本中,我们都是突然停下来的。运行完最后一条命令时,脚本就结束了。其实还有另外一种更优雅的方法可以为脚本划上一个句号。
shell中运行的每个命令都使用退出状态码(exit status)告诉shell它已经运行完毕。退出状态码是一个0~255的整数值,在命令结束运行时由命令传给shell。可以捕获这个值并在脚本中使用。
8.1 查看退出状态码
Linux提供了一个专门的变量 $? 来保存上个已执行命令的退出状态码。对于需要进行检查的命令,必须在其运行完毕后立刻查看或使用 $? 变量。它的值会变成由shell所执行的最后一条命令的退出状态码。
$ date
Sat Jan 15 10:01:30 EDT 2014
$ echo $?
0
$
按照惯例,一个成功结束的命令的退出状态码是 0 。
Linux退出状态码
状 态 码 描 述
0 命令成功结束
1 一般性未知错误
2 不适合的shell命令
126 命令不可执行
127 没找到命令
128 无效的退出参数
128+x 与Linux信号x相关的严重错误
130 通过Ctrl+C终止的命令
255 正常范围之外的退出状态码
8.2 exit 命令
默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。
[root@jerry sh]# sh test6.sh
Toe result is 2
[root@jerry sh]# echo $?
0
你可以改变这种默认行为,返回自己的退出状态码。 exit 命令允许你在脚本结束时指定一个退出状态码。
[root@jerry sh]# cat test7.sh
#!/bin/bash
#testubg the exit status
var1=10
var2=20
var3=$[$var1 + $var2]
echo The answer is $var3
exit 6
当查看脚本的退出码时,你会得到作为参数传给 exit 命令的值。
[root@jerry sh]# sh test7.sh
The answer is 30
[root@jerry sh]# echo $?
6
也可以在 exit 命令的参数中使用变量。
[root@jerry sh]# cat test7.sh
#!/bin/bash
#testubg the exit status
var1=10
var2=20
var3=$[$var1 + $var2]
exit $var3
[root@jerry sh]# sh test7.sh
[root@jerry sh]# echo $?
30
注意退出状态码最大只能是 255,下面的例子就是超过255:
[root@jerry sh]# cat test7.sh
#!/bin/bash
#testubg the exit status
var1=20
var2=20
var3=$[$var1 * $var2]
echo The value is $var3
exit $var3
[root@jerry sh]# sh test7.sh
The value is 400
[root@jerry sh]# echo $?
144
退出状态码被缩减到了0~255的区间。shell通过模运算得到这个结果。一个值的模就是被除后的余数。最终的结果是指定的数值除以256后得到的余数。在这个例子中,指定的值是 400 (返回值),余数是144,因此这个余数就成了最后的状态退出码。
bash shell脚本允许你将多个命令串起来放进脚本中。创建脚本的最基本的方式是将命令行中的多个命令通过分号分开来。shell会按顺序逐个执行命令,在显示器上显示每个命令的输出。你也可以创建一个shell脚本文件,将多个命令放进同一个文件,让shell依次执行。shell脚本文件必须定义用于运行脚本的shell。这个可以通过 #! 符号在脚本文件的第一行指定,后面跟上shell的完整路径。
在shell脚本内,你可以通过在变量前使用美元符来引用环境变量。也可以定义自己的变量以便在脚本内使用,并对其赋值,甚至还可以通过反引号或 $() 捕获的某个命令的输出。在脚本中可以通过在变量名前放置一个美元符来使用变量的值。bash shell允许你更改命令的标准输入和输出,将其重定向到其他地方。你可以通过大于号将命令输出从显示器屏幕重定向到一个文件中。也可以通过双大于号将输出数据追加到已有文件。小于号用来将输入重定向到命令。你可以将文件内容重定向到某个命令。Linux管道命令(断条符号)允许你将命令的输出直接重定向到另一个命令的输入。Linux系统能够同时运行这两条命令,将第一个命令的输出发送给第二个命令的输入,不需要借助任何重定向文件。
bash shell提供了多种方式在shell脚本中执行数学操作。 expr 命令是一种进行整数运算的简便方法。在bash shell中,你也可以通过将美元符号放在由方括号包围的表达式之前来执行基本的数学运算。为了执行浮点运算,你需要利用 bc 计算器命令,将内联数据重定向到输入,然后将输出存储到用户变量中。