shell学习笔记(2)
程序可分为:
编译类:源代码 → 编译 → 可执行文件
脚本类:解释器 bash,python,Perl,rubby
读取一行,解释一行,执行一行,速度没有编译类的程序快
bash语法
1. 判断式
test expression
[ expression ]
[[ expression ]]
注意:表达式与中括号之间要有空格
整数的判断
字符的判断
对象(文件,目录,链接等)的判断
权限的判断
1.1 整数的判断
-gt(大于),-lt(小于),-ge(>=),-le(<=),-eq(=),-ne(不等于),-a(与),-o(或)
# test 10 -gt 8
# echo $? (输出0,表示结果为真)
# [ 10 -gt 8 ] 或 [[ 10 -gt 8 ]]
# echo $?
# test 10 -gt 20
# echo $?(1)
# test 10 -eq 20
# echo $?(1)
# test 10 -ne 20
# echo $?(0)
# test 10 -gt 8 -a 10 -gt 9
# echo $?(0)
# [ 10 -gt 8 -o 10 -gt 11 ]
# echo $?(0)
例1:输入3个数,输出最大的数。
# vim test.sh
1 #!/bin/bash 2 read -p "please input three num: " A B C 3 echo $A $B $C 4 [ $A -ge $B ] && MAX=$A || MAX=$B 5 [ $C -ge $MAX ] && MAX=$C 6 echo "The max num is $MAX"
&&与||使用再举例:
# grep '^root\>' /etc/passwd &>/dev/null 等同于 # grep -q '^root\>' /etc/passwd(-q 静默模式)
# echo $?(0)
# grep -q '^root\>' /etc/passwd && echo "ok" || echo "not"
1.2 字符的比较(按ascii值比较)
=,!=,>,<
注意:当使用单中括号进行判断时,“>”或“<”需要转义后才能正常使用。当使用双中括号时,“>”或“<”不用转义即可正常使用。
# [ a > b ]
# echo $?(0)
# [ a < b ]
# echo $?(不管a > b还是a < b,返回值都是0)
正确使用方法:
# [ a \> b ](转义)或 # [[ a > b ]]
# echo $?(1)
# [ a \< b ](转义)或 # [[ a < b ]]
# echo $?(0)
# [ a = b ]
# echo $?(1)
# [ a != b ]
# echo $?(0)
-z 表示为空,未定义(null)
-n 表示非空
# [ -z "$ABC" ]
# echo $?(0)
# [ -n "$ABC" ]
# echo $?(1)
1.3 对象(文件,目录,链接,块设备,字符设备,命名管道,socket)的判断
-e 是否存在
# [ -e f1 ]
# echo $?(如果存在f1文件,则返回值为0)
为测试下面脚本,先安装apache:
# yum install httpd
# rpm -ql httpd | less
# /usr/sbin/httpd & (后台启动httpd服务)
# netstat -tupln | grep httpd
tcp 0 0 :::80 :::* LISTEN 23664/httpd
# pkill httpd
例2:编写脚本,判断在/usr/sbin目录下是否存在httpd,如果是可执行的,则启动之。
1 #!/bin/bash 2 if [ -e /usr/sbin/httpd ];then 3 if [ -x /usr/sbin/httpd ];then 4 /usr/sbin/httpd 5 else 6 echo "the httpd is not exec file." 7 fi 8 else 9 echo "the httpd is not exist." 10 fi
linux echo颜色控制:echo要改变颜色时,要使用参数 -e
格式:echo -e "\033[字背景颜色;字体颜色m字符串\033[0m"
echo -n "the httpd is starting..."(-n 表示不换行)
sleep 1
/usr/sbin/httpd && echo -e "\033[32m[ok]\033[0m" || echo "fail"
-f 是否为文件,-d 目录,-L或-h 链接,-b 块设备,-c 字符设备,-p 命名管道,-S socket
# mkdir dir1
# ln -s /etc/passwd ln1
# [ -d dir1 ]
# [ -L ln1 ]
# [ -c /dev/tty1 ]
# [ -b /dev/sda1 ]
例3:脚本运行时提示输入目录,接着输入对象名称。
判断 文件 显示.........文件
目录 显示.........目录
....
分支语句:
① 单分支
if 表达式;then
语句
fi
② 双分支
if 表达式;then
语句
else
语句
fi
③ 多分支
if 表达式1;then
语句1
elif 表达式2;then
语句2
elif 表达式3;then
语句3
......
else
当所有条件都不成立时,执行的代码
fi
例3脚本:
1 #!/bin/bash 2 read -p "please input one dir: " DIR 3 read -p "please input one object: " OBJ 4 if [ -e $DIR/$OBJ ];then 5 if [ -f $DIR/$OBJ ];then 6 echo -e "the $DIR/$OBJ is \033[31mfile\033[0m" 7 elif [ -L $DIR/$OBJ ];then 8 echo -e "the $DIR/$OBJ is \033[31mlink\033[0m" 9 elif [ -d $DIR/$OBJ ];then 10 echo -e "the $DIR/$OBJ is \033[31mdir\033[0m" 11 elif [ -b $DIR/$OBJ ];then 12 echo -e "the $DIR/$OBJ is \033[31mblock device\033[0m" 13 elif [ -c $DIR/$OBJ ];then 14 echo -e "the $DIR/$OBJ is \033[31mchar device\033[0m" 15 else 16 echo -e "the $DIR/$OBJ is \033[31munknown\033[0m" 17 fi 18 else 19 echo "the $DIR/$OBJ is not exist." 20 fi
注意:上面的脚本有点小问题,应该把链接的判断放在文件的前面。
# chmod a+x test1.sh
# ./test1.sh
please input one dir: /root
please input one object: ln1
the /root/ln1 is link
④ 多分支case语句
case 变量 in
变量值1)
语句1;;
变量值2)
语句2;;
变量值3)
语句3;;
*)
语句n;;
esac
# vim /etc/init.d/httpd(这个脚本中就使用了case语句)
用case语句改写例3:
1 #!/bin/bash 2 read -p "please input one dir: " DIR 3 read -p "please input one object: " OBJ 4 if [ -e $DIR/$OBJ ];then 5 STRING=`ls -l -d $DIR/$OBJ` 6 FIRSTCHAR=${STRING:0:1} 7 case $FIRSTCHAR in 8 -) 9 echo -e "the $DIR/$OBJ is \033[31mfile\033[0m" 10 ;; 11 d) 12 echo -e "the $DIR/$OBJ is \033[31mdir\033[0m" 13 ;; 14 L) 15 echo -e "the $DIR/$OBJ is \033[31mlink\033[0m" 16 ;; 17 b) 18 echo -e "the $DIR/$OBJ is \033[31mblock device\033[0m" 19 ;; 20 c) 21 echo -e "the $DIR/$OBJ is \033[31mchar device\033[0m" 22 ;; 23 *) 24 echo -e "the $DIR/$OBJ is \033[31munknown\033[0m" 25 ;; 26 esac 27 else 28 echo "the $DIR/$OBJ is not exist." 29 fi
FIRSTCHAR=${STRING:0:1}(从左边第0个字符开始截,截取一个字符)
例4:模拟service httpd start|stop|status
# cat /var/run/httpd/httpd.pid
# service httpd status
httpd (pid 23975) is running...
# vim httpd.sh
1 #!/bin/bash 2 case "$1" in 3 start) 4 echo -n "httpd is starting..." 5 /usr/sbin/httpd && echo -e "\033[32m[ok]\033[0m" || echo "fail" 6 ;; 7 stop) 8 pkill httpd 9 ;; 10 status) 11 if [ -e /var/run/httpd/httpd.pid ];then 12 HTTPPID=`cat /var/run/httpd/httpd.pid` 13 echo "httpd (pid $HTTPPID) is running..." 14 else 15 echo "httpd is stopped" 16 fi 17 ;; 18 *) 19 echo "Usage: httpd {start|stop|status}" 20 ;; 21 esac
练习:
1. 输入一个帐号,存在则显示其名称、uid、gid、家目录;不存在则显示不存在。
2. 手工创建帐号(不能使用useradd命令)。
浙公网安备 33010602011771号