2

Linux(基于《Linux命令行与shell脚本编程大全》的学习笔记)

11构建基本脚本

脚本运行环境为Centos7

创建shell脚本

shell 脚本的第一行用来指定要使用的shell 格式为

#!/bin/bash

通常使用# 作为shell 脚本的注释(但是第一行例外)
创建一个内容如下的脚本(文件名.sh结尾)

#!/bin/bash/
#脚本测试
date
who

完成后直接运行,使用命令bash 文件名.sh可以直接运行脚本,得到如下结果:

Sun Jun 17 20:52:35 CST 2018
root pts/0 2018-06-17 20:49

上面就是一个简单的脚本

显示消息

大多数shell命令都会产生自己的输出,这些输出会输出到控制台上,很多时候我们想添加自己的文本消息来告诉用户脚本正在做什么,这就用到了一个shell 命令 echo

echo 可以使用单引号或者双引号来划定按文本字符串,作用类似于java/python的print

可以把上面的脚本改为

#!/bin/bash/
#脚本测试
echo "现在的时间是"
date
echo "已经登录的用户有"
who

可以看到结果:

现在的时间是
Mon Jun 18 08:16:10 CST 2018
已经登录的用户有
root pts/0 2018-06-18 08:15

使用变量

环境变量

之前使用过echo 命令来查看环境变量 同样,也可以在脚本中使用$+环境变量名来获取环境变量
修改脚本为

#!/bin/bash/
#脚本测试
echo "现在的时间是"
date
echo "已经登录的用户有"
who
echo UID:$UID 
echo HOME:$HOME

执行后输出如下 :

现在的时间是
Mon Jun 18 08:36:09 CST 2018
已经登录的用户有
root pts/0 2018-06-18 08:15
root pts/1 2018-06-18 08:35
UID:0
HOME:/root

在shell脚本中只要引用了环境变量,就会显示对应的环境变量,如果要显示$HOME这样的字符,必须在使用前加转义符,否则会被shell翻译为对应的环境变量的值

用户变量

shell脚本允许脚本中自定义变量,自定义的变量允许在整个脚本中使用

用户变量可以是任何由字母、数字或下划线组成的文本字符串,长度不超过20个。用户变量区分大小写,所以变量Var1和变量var1是不同的

创建脚本内容如下 :

#!/bin/bash/
var1=10
var2=29
var3=$var1
echo 'var1的值为$var1'
echo 'var2的值为$var2'
echo 'var3的值和var1相等值为$var3'

运行结果:

var1的值为$var1
var2的值为$var2
var3的值和var1相等值为$var3

上面看到输出内容不对啊,没有拿到对应的值,这里是我的引号写错了,echo中有变量调用的时候应该使用双引号,否则无法识别变量的值,或者不使用引号
将上面的脚本修改为:

#!/bin/bash/ 
var1=10 
var2=29
var3=$var1
echo "var1的值为$var1"
echo "var2的值为$var2"
echo "var3的值和var1相等值为$var3"

执行结果:

var1的值为10
var2的值为29
var3的值和var1相等值为10

注意变量之间的赋值用的是var3=$var1而不是var3=var1,后者var3的值就是var1这个字符串了

命令替换

命令替换就是将一个命令的输出替换为脚本中的一个变量,一般有两种方法:

反引号字符 ` 例:var1=`date`

$() 例 var2=$(date)

上面两种都是将date输出的内容赋值给变量var1/2,注意赋值等号和命令之间没有空格
写个脚本测试一下

#!/bin/bash/
var1=`date`
var2=$(date)
echo "今天的日期时间1是$var1"
echo "今天的日期时间2是$var2"

运行结果:

今天的日期时间1是Mon Jun 18 10:53:39 CST 2018
今天的日期时间2是Mon Jun 18 10:53:39 CST 2018

常用下面的脚本来按日期给文件命名

#!/bin/bash  
# copy the /usr/bin directory listing to a log file  
today=$(date +%y%m%d)  
ls /usr/bin -al > log.$today  

第三行是将date格式化为年月日的形式,将/usr/bin/目录下ls命令的输出内容输入到log文件中,运行后会生成一个以日期结尾的文件

重定向输入和输出

输出重定向

最基本的重定向将命令的输出发送到一个文件中。bash shell用大于号(>)
最简单的执行命令

date > today

把今天的日期输出到today文件中 注:today文件不存在于当前目录下就会创建today文件,如果已经存在today文件,则会覆盖today中的内容(没有任何提示)
为了防止覆盖文件内容,可以使用双大于号 >> 来向文件追加内容

输入重定向

和输出重定向相反,输入重定向是使用 小于号 <
可以把符号方向理解为数据流动的方向
wc命令可以对数据数据中的文本进行计数,默认情况下会依次输出三个值,分别为:文本的行数,文本的词数,文本的字节数
执行

wc < today
1 6 29

内联输入重定向符号是远小于号(<<)。除了这个符号,你必须指定一个文本标记来划分输入数据的开始和结尾。任何字符串都可作为文本标记,但在数据的开始和结尾文本标记必须一致
执行

wc << biaoji

会进入次级提示符中(理解为一个输入框),输入对应的数据后换行输入 biaoji 即可结束,并计算两个biaoji之间的数据的信息 总体代码如下

wc << biaoji
>这里是输入的数据内容
>这也算
>biaoji

执行结果为

2 2 41

管道

管道命令格式 command1 | command2
将命令1的输出作为命令2的输入

rpm -qa|sort >rmp.list

上面的命令就是将安装包的信息排序后输入到rpm.list中 (RedHat)
管道命令用处很多也很简单

执行数学运算

expr 命令
expr 1 + 5

加号两边都有空格
一般情况不用这玩意儿,很难用,这个命令是bash shell为了兼容另一种名为Bourne shell,所以就不要用了

使用方括号

使用$[operation] 作为计算的首选
创建如下脚本

#!/bin/bash
var1=100
var2=50
var3=45
var4=$[$var1 * ($var2 - $var3)]
echo The final result is $var4

执行上面的脚本可以看到The final result is 500
注意 bash shell 只支持整数运算

浮点计算

常见的浮点计算是使用内建的bash计算器
使用命令bc 进入计算器或者bc -q 略去欢迎信息
bc可以指定结果的小数位数

$ bc -q
3.44 / 5
0
scale=4
3.44 / 5
.6880
quit

同样bc 支持变量

$ bc -q
var1=10
var1 * 4
40
var2 = var1 / 5
print var2
2
quit

在脚本中可以使用bc

#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1

脚本bc+内联输入重定向

#!/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
退出脚本

查看退出状态码

echo $?

一个成功结束的命令的退出状态码是0.如果一个命令结束有错误,退出状态码应该是一个正数值
Linux 退出状态码

状态码 描述
0 命令成功结束
1 一般性未知错误
2 不是的shell命令
126 命令不可执行
127 没有找到命令
130 通过ctrl+c终止的命令
exit 命令

默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。
exit命令允许你在脚本结束时指定一个退出状态码。
状态吗最大为255 如果超过最大的状态码,退出状态码被缩减到了0~255的区间。shell通过模运算得到这个结果。一个值的模就是被除后的余数。最终的结果是指定的数值除以256后得到的余数。在这个例子中,指定的值是300(返回值),余数是44,因此这个余数就成了最后的状态退出码。

#!/bin/bash
# testing the exit status
var1=10
var2=30
var3=$[$var1 * $var2]
echo The value is $var3
exit $var3

执行上面的脚本,其执行的状态码为300,超过了最大的255,所以会被取余为44
使用命令

echo $?

可以直接查看状态码
完~


在瘦了
38 声望5 粉丝

睿智哦