[Shell]-3-Bash基础脚本

引言

这篇文章简单的介绍Bash Shell的基本输入和概念,看看日常用到的Shell命令是如何组合到一个sh脚本里面的。

文章目录

0×1.Bash Shell中的注释

在Shell脚本中,井号( # )用作注释,Shell并不会处理井号开头的注释行,但是,Shell脚本文件的第一行是个例外,# 后面的惊叹号会告诉系统用哪个Shell来运行脚本,例如:

					#创建一个sh脚本文件
					root@qingsword.com:~# vim first.sh

					#使用more命令查看first.sh中,内容如下,
					root@qingsword.com:~# more first.sh 
					#!/bin/bash  
					#第一行告诉系统,使用哪个解释器来处理下面的命令

					#除了第一行,其他所有井号开头的都是注释
					#website:www.qingsword.com 
					#qingsword

					echo "www.qingsword.com"
					cal

					#执行脚本,得如下输出,第一行是echo输出,下面是日历
					root@qingsword.com:~# bash ./first.sh
					www.qingsword.com
					      十一月 2018        
					日 一 二 三 四 五 六  
					             1  2  3  
					 4  5  6  7  8  9 10  
					11 12 13 14 15 16 17  
					18 19 20 21 22 23 24  
					25 26 27 28 29 30 
					

这个小实例就是一个最基本的sh脚本,在Shell中,可以使用“;”分号将所有命令都放置在同一行,也能每行放置一条命令,Shell会按根据命令在文件中出现的顺序进行处理,实际上sh脚本就是shell命令的一个集合,它可以帮助我们批量的处理工作中需要重复输出的命令,提高工作效率。

0×2.修改PATH变量

可以将脚本所在目录放入PATH环境变量路径中,这样我们在任何目录中,只需要输入脚本文件名,就能够执行这些脚本,例如:

					#查看当前目录文件和路径
					root@qingsword.com:~# ls
					first.sh
					root@qingsword.com:~# pwd
					/root

					#将当前目录加入PATH变量
					root@qingsword.com:~# PATH=$PATH:/root

					#root家目录已经加入PATH环境变量末尾
					root@qingsword.com:~# echo $PATH
					/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root

					#现在切换到/home目录,然后直接输入我们创建的脚本,显示权限不够
					root@qingsword.com:~# cd /home
					root@qingsword.com:/home# first.sh 
					-bash: /root/first.sh: 权限不够

					#因为文件没有可执行权限,添加可执行文件再执行,发现在任何目录下,都可以调用这个脚本
					root@qingsword.com:/home# chmod +x first.sh 
					root@qingsword.com:/home# first.sh 
					www.qingsword.com
					      十一月 2018        
					日 一 二 三 四 五 六  
					             1  2  3  
					 4  5  6  7  8  9 10  
					11 12 13 14 15 16 17  
					18 19 20 21 22 23 24  
					25 26 27 28 29 30

					#再来看一个脚本
					root@qingsword.com:~# vim second.sh 

					root@qingsword.com:~# more second.sh 
					#!/bin/bash

					one=1  #定义环境变量
					two=2
					echo -n "Home: " $HOME #输出全局变量,-n不换行
					#因为上面echo的-n,清除了所有换行符,这一行会紧接着上一行输出,要输出"$"符,需要使用转义字符"\"
					echo " \$30 dollar" 
					echo "$one $two"  #输出局部环境变量
					date #调用系统命令

					#程序输出
					root@qingsword.com:~# chmod +x second.sh
					root@qingsword.com:~# bash second.sh 
					Home:  /root $30 dollar
					1 2
					2018年 11月 07日 星期三 21:33:41 CST
					

0×3.将命令结果赋值给变量

要想将命令返回结果赋值给变量,需要使用下面方法中的一种,第一种方法,使用“反引号”(和键盘上波浪线~在一个键上的那个符号,一般位于1的左侧);第二种方法,使用$(在括号中包含要执行的命令),例如:

					root@qingsword-v:~# vim aa.sh
					root@qingsword-v:~# more aa.sh 
					#!/bin/bash

					a=`date`  #使用反引号
					#使用$(),date后面的"+%y%m%d"格式告诉date命令将日期显示为两位数的年月日的组合
					b=$(date +%y%m%d) 

					echo $a
					echo $b
					root@qingsword-v:~# chmod +x aa.sh 
					root@qingsword-v:~# bash aa.sh 
					2018年 11月 07日 星期三 21:42:52 CST
					181107
					

0×4.输入输出重定向

输出重定向,将命令的输出保存到文件中,使用一个">"(覆盖原有文件内容),或两个">>"(将内容追加到文件末尾)来实现,例如:

					#使用重定向,将date命令输出保存到文件中
					#创建bb.sh脚本
					root@qingsword-v:~# vim bb.sh
					#输入下面的内容
					#!/bin/bash

					#如果bb.txt存在,echo输入的这段文本会覆盖bb.txt中原有文本
					echo "www.qingsword.com" > bb.txt  
					#将下面命令的输出追加到bb.txt文件末尾
					date >> bb.txt
					whoami >> bb.txt

					#添加可执行权限,执行
					root@qingsword-v:~# chmod +x bb.sh
					root@qingsword-v:~# bash bb.sh

					#查看执行结果,创建了一个bb.txt,并且使用重定向命令,将命令结果输入到这个文本中
					root@qingsword-v:~# more bb.txt 
					www.qingsword.com
					2018年 11月 08日 星期四 16:13:07 CST
					root
					

输入重定向就是将文件的内容读取,传递给命令,例如:

					#在bb.txt中不按顺序写入1~5的数字
					root@qingsword-v:~# echo 4 > bb.txt
					root@qingsword-v:~# echo 1 >> bb.txt
					root@qingsword-v:~# echo 3 >> bb.txt
					root@qingsword-v:~# echo 5 >> bb.txt
					root@qingsword-v:~# echo 2 >> bb.txt
					root@qingsword-v:~# more bb.txt
					4
					1
					3
					5
					2
					#使用输入重定向,将bb.txt文件传递给sort命令进行排序,排序后的输出如下(这和直接使用sort bb.txt输出完全相同)
					root@qingsword-v:~# sort < bb.txt
					1
					2
					3
					4
					5
					

下面来看一个比较实用的输入输出重定向实例:

					#cat命令不仅仅可以用来显示文件中的内容,使用输入重定向,它可以将键盘输入的内容传递给后面的文件
					root@qingsword-v:~# cat > bb.txt
					a
					b
					c
					d
					e
					f
					www.qingsword.com
					^C  #如果要结束输入,需要按键盘的"ctrl+c"组合件

					#查看刚才使用输入重定向保存的文件内容
					root@qingsword-v:~# more bb.txt
					a
					b
					c
					d
					e
					f
					www.qingsword.com
					

除此之外,还有一个十分好用的方法读取键盘的输入保存到文件中。

使用内联输入重定向,在内联输入重定向中,当Shell看到<<的时候,它就会知道下一个词是一个分界符(本例中是qingsword,很多例子中,这个词被取名为EOF,它是End Of File的缩写),在该分界符以后的内容都被当作输入,直到Shell又看到该分界符(位于单独的一行);这个分界符可以是你所定义的任何字符串。

					#通过上面解释,下面的命令就可以理解为,向cc.txt中追加内容(因为使用了两个>>,所以是追加,如果是一个>,当cc.txt存在,输入的内容将覆盖cc.txt原有内容),直到在单独的一行中键入"qingsword"作为结束
					root@qingsword-v:~# cat >> cc.txt << qingsword
					> www.qingsword.com
					> qingsword.com
					> welcome to my website
					> qingsword

					#查看刚才的输入
					root@qingsword-v:~# cat cc.txt
					www.qingsword.com
					qingsword.com
					welcome to my website

					#上面这个实例的另一种实现方法,两种写法效果相同
					root@qingsword-v:~# cat << qingsword >> dd.txt
					> www.qingsword.com
					> test
					> dd.txt
					> dd end
					> qingsword
					root@qingsword-v:~# cat dd.txt
					www.qingsword.com
					test
					dd.txt
					dd end
					

0×5.管道命令基础

管道命令(和键盘上\在一个键上的 | 符号),可以将管道符号左边命令的输出作为管道符号右边命令的输入,例如:

					#在上面一小节中,我们创建了一个这样的文件
					root@qingsword-v:~# cat dd.txt 
					www.qingsword.com
					test
					dd.txt
					dd end

					#使用管道命令,首先cat显示dd.txt内容,再将这些内容当做wc命令的输入,统计行数
					root@qingsword-v:~# cat dd.txt | wc -l
					4
					
					#grep筛选出包含dd的两行,如下
					root@qingsword-v:~# cat dd.txt | grep dd
					dd.txt
					dd end

					#一条命令中可以包含多个管道,在上面这条命令的基础上,再添加一个管道,cat显示dd.txt内容,用grep筛选出包含dd的行,再从这两行中筛选出结尾为.txt的行
					root@qingsword-v:~# cat dd.txt | grep dd | grep .txt
					dd.txt
					

0×6.数学计算基础

在Bash Shell中,数学运算一直都不是强项,也不常用,下面介绍几种被Bash Shell支持的数学运算方式。

1、将数学运算放在"$[]"中,例如:

					root@qingsword-v:~# echo $[1+1]
					2
					root@qingsword-v:~# echo $[2*2]
					4
					#这种方法的优点是方便,缺点是不能支持浮点运算,Shell对运算的结果取整
					root@qingsword-v:~# echo $[11/3]
					3
					

2、使用bc程序运算(支持浮点数),例如:

					#创建ee.sh
					root@qingsword-v:~# vim ee.sh
					
					#输入下面的内容
					#!/bin/bash
					v1=11
					v2=3
					#echo将scale=4以及$v1/$v2传递给bc程序,v1和v2被11和3替换,scale是bc支持的设定精确小数点到多少位的一个参数(这就相当于在Shell下输入bc命令,进入bc程序输入界面,然后再输入scale=4,再输入11/3,得到结果)
					v3=$(echo "scale=4;$v1/$v2" | bc)
					echo $v3

					#运行脚本,得到一个结果,保留四位小数
					root@qingsword-v:~# bash ee.sh
					3.6666
					

bc程序的另一种用法:

					#创建一个ff.sh,内容如下
					root@qingsword-v:~# vim ff.sh
					#!/bin/bash

					#使用内联重定向的方法调用bc
					v1=11
					v2=3
					v3=55
					v4=$(bc << qingsword
					scale=4 #设置精确小数点后四位
					xx=$v1/$v2
					#注意这里,在bc内部赋值的变量不需要使用$调用,但在bc外赋值的环境变量需要使用$调用
					yy=xx+$v3
					xx+yy #将xx的值加上yy的值,结果返回给v4
					qingsword
					)
					echo $v4

					#执行结果
					root@qingsword-v:~# bash ff.sh 
					62.3332
					

0×7.Shell退出状态符

Linux提供了一个专门的变量 "$?" 来保存上个已执行命令的退出状态码;对于需要进行执行状态检查的命令,可以在其运行完毕后立刻使用 $? 查看执行结果,它的值会变成由Shell所执行的最后一条命令的退出状态码,每个状态码所代表的意思如下:

0 命令成功结束;
1 一般性未知错误;
2 不适合的shell命令;
126 命令不可执行;
127 没找到命令;
128 无效的退出参数;
128+x 与Linux信号x相关的严重错误;
130 通过Ctrl+C终止的命令;
255 正常范围之外的退出状态码;

下面来演示几个状态码:

					#命令成功结束
					root@qingsword-v:~# echo "www.qingsword.com"
					www.qingsword.com
					root@qingsword-v:~# echo $?
					0

					#没找到命令
					root@qingsword-v:~# qingsword
					qingsword:未找到命令
					root@qingsword-v:~# echo $?
					127

					#命令不可执行
					root@qingsword-v:~# ./ee.sh
					-bash: ./ee.sh: 权限不够
					root@qingsword-v:~# echo $?
					126

					#通过Ctrl+C终止的命令(启动一个子bash,然后用Ctrl+C终止)
					root@qingsword-v:~# bash
					root@qingsword-v:~# ^C
					root@qingsword-v:~# echo $?
					130