[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