1

时间:2017年08月28日星期一
说明:本文部分内容均摘取自书籍《Linux命令行与shell脚本编程大全》,版权归原作者所有。《Linux命令行与shell脚本编程大全》(第三版)第十一章学习总结

第十一章:构建基本脚本

本章内容

使用多个命令
创建脚本文件
显示消息
使用变量
输入输出重定向
管道
数据运算
退出脚本

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

说明:也可以通过${variable}形式引用变量。变量名两侧额外的花括号通常用来帮助识别美元符后的变量名。如果要显示$符号,则需要使用进行转义,如:\$

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

警告:命令替换会创建一个子shell来运行对应的命令。子shell(subshell)是由运行该脚本的shell所创建出来的一个独立的子shell(child shell)。正因为如此,由该子shell所执行命令是无法使用脚本中所创建的变量的。在命令行提示符下使用路径./运行命令的话,也会创建出子shell;要是运行命令的时候不加入路径,就不会创建子shell。

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:指定退出状态码

妙手空空
1.3k 声望368 粉丝

博观而约取,厚积而薄发