一、什么是shell
简单点理解,就是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。实际上,在shell和计算机硬件之间还有一层东西那就是系统内核了。打个比方,如果把计算机硬件比作一个人的躯体,而系统内核则是人的大脑,至于shell,把它比作人的五官似乎更加贴切些。回到计算机上来,用户直接面对的不是计算机硬件而是shell,用户把指令告诉shell,然后shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作。
试验环境为linux发布版本(Redhat/CentOS)系统默认安装的shell叫做bash,即Bourne Again Shell,它是sh(Bourne Shell)的增强版本。Bourn Shell 是最早行起来的一个shell,创始人叫Steven Bourne,为了纪念他所以叫做Bourn Shell,检称sh。
二、linux shell中的特殊符号
1、 * :代表零个或多个字符或数字。
2.、 ? :只代表一个任意的字符。
3、 # :这个符号在linux中表示注释说明的意思,即”#”后面的内容linux忽略掉。
在命令的开头或者中间插入”#” ,linux都会忽略掉的。这个符号在shell脚本中用的很多。
4.、 \ :脱意字符,将后面的特殊符号(例如”\*” )还原为普通字符。
5、 | :管道符,它的作用在于将符号前面命令的结果丢给符号后面的命令。这里提到的后面的命令,并不是所有的命令都可以的,一般针对文档操作的命令比较常用,例如cat, less, head, tail, grep, cut, sort, wc, uniq, tee, tr, split, sed, awk等等,其中grep, sed, awk为正则表达式必须掌握的工具。
6、 $ :除了用于变量前面的标识符外,还有一个妙用,就是和‘!‘结合起来使用。
‘!$‘表示上条命中中最后一个变量(也许称为变量不合适,总之就是上条命令中最后出现的那个东西)。
三、shell脚本结构以及执行方法
1、shell脚本的结构
开头行指定bash路径: #! /bin/bash 、以#开头的行作为解释说明 、脚本的名字以.sh结尾,用于区分这是一个shell脚本。
2、shell脚本的执行方法
[[email protected] shell]# cat test1.sh //创建第一个脚本
#!/bin/bash
echo "hello world!"
[[email protected] shell]# ll
总用量 4
-rw-r--r-- 1 root root 33 6月 24 08:12 test1.sh
[[email protected] shell]# chmod a+x test1.sh
[[email protected] shell]# ./test1.sh //第一种执行脚本的方法,记住这种方法要将脚本添加X的权限
hello world!
[[email protected] shell]# /root/shell/test1.sh //或者使用绝对路径,但一定要有X的权限
hello world!
[[email protected] shell]# bash test1.sh //第二种执行脚本的方法,下面三个与这个类是,但是在写脚本时脚本内最好写绝对路径避免出错
hello world!
[[email protected] shell]# sh test1.sh
hello world!
[[email protected] shell]# /bin/bash test1.sh
hello world!
[[email protected] shell]# /bin/sh test1.sh
hello world!
[[email protected] shell]# /bin/sh -x test1.sh //这样可以查看脚本的执行过程,在今后编写脚本出错时可以用这排错
+ echo ‘hello world!‘
hello world!
四、date命令的简介
1、常用选项及其显示形式
[[email protected] shell]# date +%Y //%Y 显示完整的年份
2015
[[email protected] shell]# date +%y //%y 年的最后两个数字(1999则是99)
15
[[email protected] shell]# date +%M //%M 分钟(00~59)
07
[[email protected] shell]# date +%m //%m 月份(01~12)
06
[[email protected] shell]# date +%d //%d 一个月的第几天(01~31)
24
[[email protected] shell]# date +%h //%h 月的简称(Jan~Dec)
6月
[[email protected] shell]# date +%H //%H 小时,24小时制(00~23)
09
[[email protected] shell]# date +%s //%s 从1970年1月1日00:00:00到目前经历的秒数
1435108154
[[email protected] shell]# date +%S //%S 显示秒(00~59)
08
[[email protected] shell]# date +%F //%F 显示年月日
2015-06-24
[[email protected] shell]# date +%Y-%m-%d //和%F表示的一样
2015-06-24
[[email protected] shell]# date +%T //%T 显示时间,24小时制(hh:mm:ss)
09:24:40
[[email protected] shell]# date +%H:%M:%S //和%T表示的一样
10:33:57
[[email protected] shell]# date +%w //%w 一个星期的第几天(0代表星期天)
3
[[email protected] shell]# date +%W //%W 一年的第几个星期(00~53,星期一为第一天)
25
[[email protected] shell]# date +%j //%j 一年的第几天(001~366)
175
[[email protected] shell]# date +%Z //%Z 显示时区,日期域(CST)
CST
[[email protected] shell]# date +%a //%a 星期的简称(Sun~Sat)
三
[[email protected] shell]# date +%A //%A 星期的全称(Sunday~Saturday)
星期三
[[email protected] shell]# date +%D //%D 日期(mm/dd/yy)
06/24/15
[[email protected] shell]# date -d @100 //显示从1970年1月1日00:00:00经历100秒的显示
1970年 01月 01日 星期四 08:01:40 CST
[[email protected] shell]# date -d "-1 day" +"%F %T" //显示一天前的当前时间,同时可以将“-”改为“+”表示一天后的当前时间,也可以把day改为month(月)、year(年)、week(周)、hour(小时)、min(分钟)、sec(秒)。
2015-06-23 23:59:24
五、shell脚本中的变量
1、引用某个命令的结果,使用变量代替
[[email protected] shell]# file=`which vim` //注意等号左右不能有空格
[[email protected] shell]# echo $file
/usr/bin/vim
[[email protected] shell]# rpm -qf $file
vim-enhanced-7.2.411-1.8.el6.i686
上面三个操作为定义了file这个变量存放的是vim命令的存放路径,然后让rpm命令通过调用file这个变量的内容来查询vim命令的安装包
[[email protected] shell]# rpm -qf `which vim` //等同于上面的操作结果,但是不是很容易理解,今后在写脚本中经常遇到。
vim-enhanced-7.2.411-1.8.el6.i686
扩展学习:变量file只是在当前shell环境生效,要是进入子shell就无法使用,若要想在子shell也能使用则要在命令行使用export声明为全局变量。但是声明后的变量虽然能在子shell中使用,但是一旦另开立一个终端就无法生效了,若还想在别的终端使用则要把export声明全局变量写到/etc/profile、/etc/bashrc 或者家目录的.bash_profile、.bashrc四个文件的任意一个。在写入后还要记住前两个文件是所有用户都能使用,而后两个只能是家目录所在的用户才能使用。
2、参数的变量:
[[email protected] shell]# cat test3.sh
#!/bin/bash
echo "\$0=$0"
echo "\$1=$1"
echo "\$2=$2"
echo "\$3=$3"
echo "\$#=$#"
[[email protected] shell]# sh test3.sh movies longls bols cangls
$0=test3.sh
$1=movies
$2=longls
$3=bols
$#=4
通过上例可是发现$0为shell脚本本身,$1为手动输入的第一个参数,$2为手动输入的第二个参数,$3为手动输入的第三个参数,$#为统计一共输入了多少个参数,显示4是由于脚本定义的显示参数的变量就三个,所以第四个参数camgls没有给打印出来。
3、数值运算的方法
[[email protected] shell]# aa=11;bb=22
[[email protected] shell]# cc=$aa+$bb
[[email protected] shell]# echo $cc //不支持直接运算
11+22
[[email protected] shell]# cc=$(($aa+$bb))
[[email protected] shell]# echo $cc
33
[[email protected] shell]# cc=$[$aa+$bb]
[[email protected] shell]# echo $cc
33
通过上例可以发现在shell环境下做数值运算时直接进行运算会出现不是我们所要的结果,而若要正确使用数值运算则要添加[]或者(())来进行运算才能达到想要的运算结果。
六、shell脚本的逻辑判断if
1、if语句的格式
格式1:if 条件 ; then 语句; fi
格式2:if 条件; then 语句; else 语句; fi
格式3:if …; then … ;elif …; then …; else …; fi
2、if语句逻辑判断表达式
if [ $a -gt $b ] //gt大于
if [ $a -lt 5 ] //lt小于
if [ $b -eq 10 ] //eq等于
对于if语句的判断表达式一定要注意在中括号内的空格,为增加shell的可读性建议在数值运算的表达式用两个小括号(()),若用中括号[]可能会和在逻辑判断表达式一块使用时出错。在shell中很少用<、>、=等运算符号,会使用gt、lt等表示运算符号下面介绍下用字母表示运算符。
大于 > gt (greater than)
小于 < lt (less than)
大于等于 >= ge
小于等于 <= le
等于 == eq(equal)
不等于 != ne
3、 if 判断文件、目录属性
[ -f file ]判断是否是普通文件,且存在
[ -d file ] 判断是否是目录,且存在
[ -e file ] 判断文件或目录是否存在
[ -r file ] 判断文件是否可读
[ -w file ] 判断文件是否可写
[ -x file ] 判断文件是否可执行
4、应用举例
手动输入两个数字并判断两个数字的大小:
[[email protected] shell]# cat test4.sh
#!/bin/bash
read -p "请输入一个数字a= " a
read -p "请输入一个数字b= " b
if [ $a -eq $b ]
then
echo "a等于b"
elif [ $a -lt $b ]
then
echo "a小于b"
else
echo "a大于b"
fi
[[email protected] shell]# sh test4.sh
请输入一个数字a= 3
请输入一个数字b= 6
a小于b
判断输入的是否为数字,若不是直接退出,若是判断其为奇数还是偶数:
[[email protected] shell]# cat test5.sh
#!/bin/bash
read -p "请输入数字a= " a
n1=`echo $a |grep -c [^0-9]` //匹配输入的字符为非数字的行数,如果为1说明不是数字。
if [ $n1 -eq 1 ]
then
echo "你输入的不是数字"
exit 1
fi
n2=$(($a%2))
if [ $n2 -eq 1 ]
then
echo "你输入的是奇数"
else
echo "你输入的是偶数"
fi
[[email protected] shell]# sh test5.sh
请输入数字a= 45
你输入的是奇数
[[email protected] shell]# sh test5.sh
请输入数字a= fdgsd
你输入的不是数字
判断在目录内的文件是普通文件还是目录文件:
[[email protected] shell]# cat test6.sh
#!/bin/bash
read -p "请输入文件或者目录名: " a
if [ -f $a ]
then
echo "这是一个普通文件"
elif [ -d $a ]
then
echo "这是一个目录文件"
else
echo "这不是普通文件也不是目录文件"
fi
[[email protected] shell]# ll
总用量 28
drwxr-xr-x 2 root root 4096 6月 25 05:20 cangls
-rwxr-xr-x 1 root root 33 6月 24 08:12 test1.sh
-rw-r--r-- 1 root root 64 6月 25 00:28 test2.sh
-rw-r--r-- 1 root root 83 6月 25 00:33 test3.sh
-rw-r--r-- 1 root root 208 6月 25 03:55 test4.sh
-rw-r--r-- 1 root root 253 6月 25 04:18 test5.sh
-rw-r--r-- 1 root root 229 6月 25 05:24 test6.sh
[[email protected] shell]# sh test6.sh
请输入文件或者目录名: cangls
这是一个目录文件
[[email protected] shell]# sh test6.sh
请输入文件或者目录名: test1.sh
这是一个普通文件
三个小脚本的总结:
通过上面三个比较简单的脚本让我们大概了解下shell脚本的基本编程思路,其中特别是最后一个例子,我们可以在添加链接文件、套接字文件等的判断,总之在编程上我们还需要多动手实践,虽然上面的例子比较简单但我在自己做时还是会出现少空格,关键字写错,少写关键字的现象,所以在今后我们编程时一定要细心、冷静等良好的编程习惯,这样才能在今后的工作中保持高效^_^。