第十一章:构建基本脚本
本章内容
使用多个命令
创建脚本文件
显示消息
使用变量
输入输出重定向
管道
数据运算
退出脚本
11.1 使用多个命令
shell脚本的关键在于输入多个命令并处理每个命令的结果,甚至需要将一个命令的结果传给另一个命令。shell可以让你将多个命令串起来,一次执行完成。如果要两个命令一起运行,可以把它们放在同一行中,彼此用分号隔开。最大命令行字符数不超过255个字符。
命令演示:date ; who
命令说明:先执行date显示当前日期和时间,然后执行who显示当前是谁登陆到了系统上
使用这种方式,在每次运行之前,都必须在命令提示符下输入整个命令。可以将这些命令组合成一个简单的文本文件,这样就不需要在命令行中手动输入了。
11.2 创建shell脚本文件
命令演示:vim test1
命令说明:创建一个名为test1的文件
在创建shell脚本文件时,必须在文件的第一行指定要使用的shell,格式为
#!/bin/bash
在通常的shell脚本中,井号(#)用作注释行。shell并不会处理shell脚本中额注释行。但shell脚本文件的第一行是个例外,#后面的惊叹号会告诉shell用哪个shell来运行脚本。
使用vim编辑test1并保存
#!/bin/bash
# my shell script
date
who
命令演示:echo $PATH
命令说明:查看PATH环境变量
命令演示:chmod u+x test1
命令说明:通过chmod命令赋予文件属主执行文件的权限
命令演示:./test1
命令说明:运行在当前目录下的test1脚本
11.3 显示消息
命令格式:echo "msg"
命令说明:显示 echo后面的文本字符串msg
命令格式:echo -n "msg"
命令说明:显示echo后面的文本字符串且不换行
修改test1如下保存并运行查看效果
#!/bin/bash
# my shell script
echo -n The time and date are:
date
echo "Let's see who's logged init the system:"
who
11.4 使用变量
11.4.1 环境变量
命令演示:set
命令说明:显示当前环境变量列表
命令演示:$UID
命令说明:通过美元符($)来使用环境变量
使用vim编写test2如下并运行
#!/bin/bash
# display user infomation from the system.
echo "User info for userid: $USER"
echo UID: $UID
echo HOME: $HOME
说明:也可以通过符号,则需要使用进行转义,如:$
11.4.2 用户变量
用户变量
变量允许临时存储数据并在整个脚本中使用
由字母、数字或下划线组成,长度不超过20个
特别注意变量名区分大小写
使用等号进行赋值,且等号两边不能出现空格
例如:var1=10、var2="still more testing"
shell脚本自动识别决定变量值的数据类型
通过美元符号引用
使用vim编写test3如下
#!/bin/bash
days=10
guest="Katie"
echo "$guest checked in $days days ago"
days=5
guest="Jessica"
echo "$guest checked in $days days ago"
引用一个变量值时需要使用美元符,而引用变量来对其进行赋值时则不要使用美元符
使用vim编写test4如下
#!/bin/bash
value1=10
value2=$value1
echo The resulting value2 is $value2
value3=value1
echo The resulting value3 is $value3
11.4.3 命令替换
shell脚本中最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量。把输出赋给变量之后,就可以随意在脚本中使用了。
有两种方法可以将命令输出赋给变量
反引号字符(`):testing=`date`
$()格式:testing=$(date)
使用vim编写test5如下
#!/bin/bash
# copy the /usr/bin directory listing to a log file
today=$(date +%y%m%d)
ls /usr/bin -al > log.$today
11.5 重定向输入和输出
11.5.1 输出重定向
命令格式:command > outputfile
命令说明:使用大于号(>)重定向将命令的输出发送到一个文件中
命令演示:date > test6
命令说明:重定向操作符创建了一个文件test6,并将date命令的输出重定向到该文件中,
如果文件已经存在,则会覆盖已有文件
命令演示:date >> test6
命令说明:将date命令的输出追加到test6文件中
11.5.2 输入重定向
命令格式:command < inputfile
命令说明:使用小于号(<)输入重定向将文件的内容重定向到命令
简单的记忆方法:在命令行上,命令总是在左侧,而重定向符号“指向”数据流动的方向。小于号说明数据正在从输入文件流向命令
命令演示:wc < test6
命令说明:使用wc命令对数据中的文本进行计数。
默认情况下,它会输出3个值
文本的行数
文本的词数
文本的字节数
命令格式:command << marker
data
marker
命令说明:内联输入重定向。使用远小于符号(<<),
指定一个文本标记来划分输入数据的开始和结尾。
命令演示:wc << EOF
test string 1
test string 2
test string 3
EOF
命令说明:使用wc命令对输入的文本内容进行计数
11.6 管道
有时需要将一个命令的输出作为另一个命令的输入。可以将一个命令的输出直接重定向到另一个命令,这个过程叫作管道连接。
管道连接
命令格式:command1 | command2
使用符号:|
不要以为由管道串起来的两个命令为依次执行。
Linux系统实际上会同时运行这两个命令,在系统内部将它们连接起来。
在第一个命令产生输出的同时,输出会被立即送给第二个命令
数据传输不会用到中间文件或缓冲区
命令演示:apt list | sort | more
命令说明:显示已安装的软件包并排序并安装more命令来显示
命令:more。常用操作
按Space键:显示文本的下一屏内容
按Enter键:只显示文本的下一行内容
按斜线符|:接着输入一个模式,可以在文本中寻找下一个相匹配的模式
按H键:显示帮助屏,该屏上有相关的帮助信息
按B键:显示上一屏内容
按Q键:退出rnore命令
11.7 执行数学运算
11.7.1 expr命令
命令:expr
命令说明:使用expr命令在命令行上处理数学表达式,特别笨拙
命令演示:expr 1 + 5
命令说明:计算1+5的值
expr命令操作符
ARG1 | ARG2:如果ARG1既不是null也不是零值,返回ARG1;否则返回ARG2
ARG1 & ARG2:如果没有参数是null或零值,返回ARG1;否则返回0
ARG1 < ARG2:如果ARG1小于ARG2,返回1;否则返回0
ARG1 <= ARG2:如果ARG1小于或等于ARG2,返回1;否则返回0
ARG1 = ARG2:如果ARG1等于ARG2,返回1;否则返回0
ARG1 != ARG2:如果ARG1不等于ARG2,返回1;否则返回0
ARG1 >= ARG2:如果ARG1大于或等于ARG2,返回1;否则返回0
ARG1 > ARG2:如果ARG1大于ARG2,返回1;否则返回0
ARG1 + ARG2:返回ARG1和ARG2的算术运算和
ARG1 - ARG2:返回ARG1和ARG2的算术运算差
ARG1 * ARG2:返回ARG1和ARG2的算术乘积
ARG1 / ARG2:返回ARG1和ARG2的算术商(注意:只支持整数运算)
ARG1 % ARG2:返回ARG1和ARG2的算术余数
STRING:REGEXP:如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配
match STRING REGEXP:如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配
substr STRING POS LENGTH:返回起始位置为POS(从1开始计数)、长度为LENGTH子字符串
index STRING CHARS:返回在STRING中找到CHARS字符串的位置;否则,返回0
length STRING:返回字符串STRING的数值长度
+ TOKEN:将TOKEN解释成字符串,即使是个关键字
(EXPRESSION):返回EXPRESSION的值
修改test6脚本
#!/bin/bash
var1=10
var2=20
var3=$(expr $var2 / $var1)
echo The result is $var3
在使用的时候,注意对特殊符号进行转义。在脚本中使用expr命令比较复杂。
11.7.2 使用方括号
命令格式:$[ operation ]
命令说明:使用美元符和方括号将数学表达式围起来。
这种方式比用expr命令方便,也适用于shell脚本。
编写test7脚本
#!/bin/bash
var1=100
var2=50
var3=45
var4=$[$var1 * ($var2-$var3)]
echo The final result is $var4
编写test8脚本
#!/bin/bash
# 只支持整数运算
var1=100
var2=45
var3=$[$var1 / $var2]
echo The final result is $var3
11.7.3 浮点解决方案
1.bc的基本用法
bc是內建的bash计算器,用于解决bash中数学运算的整数限制
bash计算器可以识别
数字(整数和浮点数)
变量(简单变量和数组)
注释(以#或C语言中的/* */开始的行)
表达式
编程语句(例如if-then语句)
函数
命令格式:bc
命令说明:访问bash计算器
命令格式:quit
命令说明:进入bash计算器后,输入quit退出bash计算器
2.在脚本中使用bc
命令格式:variable=$(echo "options;expression" | bc)
命令说明:使用命令替换运行bc命令,并将输出赋给一个变量。
options允许你设置变量,多个变量用分号隔开
expression参数定义了通过bc执行的数据表达式
编写test9脚本
#!/bin/bash
# 使用scale指定小数点后的位数
var1=$(echo "scale=4;3.44 / 5" | bc)
echo The answer is $var1
编写test10脚本
#!/bin/bash
var1=100
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo The answer for this is $var3
编写test11脚本
#!/bin/bash
var1=20
var2=3.14159
var3=$(echo "scale=4; $var1 * $var2" | bc)
var4=$(echo "scale=4; $var3 * $var2" | bc)
echo The final result is $var4
内联重定向
命令格式:variable=$(bc << EOF
options
statements
expressions
EOF)
命令说明:使用内联重定向数据进行命令替换符号将bc命令的输出赋给变量
编写test12脚本
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale=4
a1 = ( $var1 * $var2)
b1 = ( $var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5
11.8 退出脚本
11.8.1 查看退出状态码
shell中运行的每个命令都使用退出状态码(exit status)告诉shell它已经运行完毕。退出状态码是一个0~255的整数值,在命令结束运行时由命令传给shell。可以捕获这个值并在脚本中使用。
命令格式:$?
命令说明:查看由shell所执行的最后一条命令的退出状态码
命令演示:echo $?
命令说明:显示由shell所执行的最后一条命令的退出状态码
Linux错误退出状态码没有什么标准可循,但有一些有用的参考
0:命令成功结束
1:一般性未知错误
2:不适合的shell命令
126:命令不可执行(表明用户没有执行命令的正确权限)
127:没找到命令
128:无效的退出参数
128+x 与Linux信号x相关的严重错误
130:通过Ctrl+C终止的命令
255:正常范围之外的退出状态码
11.8.2 exit命令
默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。exit命令允许你在脚本结束时指定一个退出状态码
编写test13脚本
#!/bin/bash
var1=10
var2=30
var3=$[$var1 + $var2]
echo The answer is $var3
exit 5
编写test14脚本
#!/bin/bash
var1=10
var2=30
var3=$[$var1 + $var2]
echo The answer is $var3
exit $var3
编写test14b脚本
#!/bin/bash
var1=10
var2=30
var3=$[$var1 * $var2]
echo The value is $var3
exit $var3
当指定的退出状态码超过255时,最终的结果是指定的数值除以256后得到的余数。在下一章,通过使用if-then语句来检查某个命令返回的错误状态,以便知道命令是否成功。
11.9 小结
bash shell脚本允许你将多个命令串起来放进脚本中。讲解了shell脚本的基本结构,变量的使用以及管道命令和算术运算,最后介绍了退出状态码。本章介绍了echo、()、>、>>、<、<<、|、expr、$[]、bc、exit命令。
本章学习命令个人总结如下
echo:显示消息
$:取变量值
$():命令替换
>:输出重定向(覆盖数据)
>>:输出重定向(追加数据)
<:输入重定向
<<:内联输出重定向
|:管道命令
expr:处理数据表达式进行算术运算
$[]:被方括号包围的内容进行算术运算
bc:bash计算器进行浮点数算术运算
exit:指定退出状态码