shell细节决定高度
1.文件测试操作符
-f[file]:文件存在且为普通文件则为真;
-d[directory]:文件存在且为目录文件则为真;
-s[size]:文件存在且为文件大小不为0则为真;
-e[exist]:文件存在则为真,比-f和-d加起来还要宽泛.
man test # 寻找系统文档帮助 # 高效简洁的判断 file1=/etc/service file2=/etc/rc.local [ -f "$file1" ] && echo 1 || echo 0 [ -f /etc/sysconfig/network ] && ./etc/sysconfig/network [ -f "$file2" ] || exit 5 &&连接的两条命令,是'生死与共'的关系,前一条执行正确,后面的就跟着执行; ||连接的两条命令,是'你死我活'的关系,前一条执行结果为假,后面的才执行. [ $1 -eq 3 ] || { echo "input";echo "is'not";echo "3";}
2.字符串测试操作符
-z "字符串":若串长度为0则为真,-z zero;
-n "字符串":若串长度不为0则为真,-n nonzero;
"串1" = "串2":若串1等于串2则为真,可以用"=="代替"=";
"串1" != "串2":若串1不等于串2则为真,不能用"!=="代替"!=",意思是:只存在"!=",不存在"!=="这种写法.
[ -z "$NFS_V2" ] && NFS_V2=default # 如果变量为空,就给个默认值 注意: a.字符串操作符务必用双引号引起来; b.比较符号的两端必须有空格. 不加空格的反例: [ "asd"=="1" ]&& echo 1 || echo 0 1 [ "asd" == "1" ]&& echo 1 || echo 0 0
3.整数比较操作符
在[]以及test中使用的比较符:-eq、-gt、-lt等;
在(())以及[[]]中使用的比较符(数学符号):=、>、<等;
整数比较不用加双引号了;[[]]用-eq的写法也是对的,[[]]用>写法也可能不对,只会比较第一位,逻辑结果不对;
所以整数比较最好用-eq、-gt、-lt等.
[[ 2 > 1 ]]&& echo 1 || echo 0 1 [[ 2 > 11 ]]&& echo 1 || echo 0 1 [[ 2 > 31 ]]&& echo 1 || echo 0 0
4.逻辑连接符
-a相当于&&:与,两端都为真才为真;
-o相当于||:或,两端都为假才为假; !:非.
注意: []中用-a、-o、!,test用法和[]相同; [[]]中用&&、||、!;
在单中括号[]中只能用-a、-o、!,不能用&&,&&只能在双中括号[[]]或两条命令之间使用:
[[ -f "$f1" && -f "$f2" ]] 或 [ -f "$f1" ] && [ -f "$f2" ]
5.分支与循环结构
a.单分支结构
if [条件];then 指令集 fi 相当于条件表达式的:[ -f "$f1" ] && echo 1
b.双分支结构
if [条件];then 指令集1 else 指令集2 fi 相当于条件表达式的:[ -f "$f1" ] && echo 1 || echo 0
c.三分支结构
if 条件1;then 指令集1 elif 条件1;then 指令集2 else 指令集3 fi
6.监控mysql时注意事项:
a.监控nginx、mysql时,脚本名不要写成check_nginx.sh或check_mysql.sh,这样的写法,会让脚本也被当成一个进程,影响判断;
b.[ "`netstat -lnp | grep 3306|awk -F "[ :]+" '{print $5}'`" -eq 3306 ],在进程不存在时这样判断会报错,因为你拿一个空字符串和数字去比较(太啰嗦,一般不用),正确的写法:[ "`netstat -lnp | grep 3306|awk -F "[ :]+" '{print $5}'`" = '3306' ]
c.其他几种写法:
[ `ps -ef|grep -v grep|grep mysqld|wc -l` -gt 0 ] [ `netstat -lntup|grep mysqld|wc -l` -gt 0 ] [ `lsof -i :3306|wc -l` -gt 0 ] # 监控远程主机端口的存活状态 [ `nc -w 2 10.0.0.7 3306 &>/dev/null && echo 1 | wc -l` -gt 0 ] [ `nmap 10.0.0.7 -p 3306 2>/dev/null|grep open|wc -l` -gt 0 ] [ "`curl -I http://10.0.0.25 2>/dev/null|head -1|egrep '200|301|302'|wc -l`" = "1" ] [ "`curl -s dev.qingfeng.com:801/svn/ &>/dev/null && echo $?`" = "0"]
7.shell特殊变量
$0:当前脚本的文件名;
$n:传递给脚本或函数的参数.n是一个数字,表示第几个参数.例如:第一个参数是$1,第二个参数是$2;
$#:传递给脚本或函数的参数个数;
$*:传递给脚本或函数的所有参数;
$?:上个命令的退出状态,或函数的返回值;
$$:当前Shell进程ID.对于 Shell 脚本,就是这些脚本所在的进程ID.
8.取变量或字符串的长度:
a.echo "$1" | wc -L
b.echo ${#1}
c.expr length "$1"
9.整数运算的方法:
a.$[]:num=$[ $1 + $2 ]
b.(()):num=$(($1+$2))
c.expr:运算符号两边必须加空格,不加空格会原样输出:
命令行:expr 1 + 2 expr $1 + $2 num=`expr $1 + $2`
d.let:let num=$1 + $2
bc:可以计算浮点数,效率较低的一种,服务器可能没有安装
i=2 i=`echo $i+3|bc` echo 3.5+6.3 | bc echo "scale=2;6.5*5.3"|bc # scale保留几位小数 echo "10.2 3.3" | awk '{print ($1-$2)}' # 计算从1加到10,并列出整个式子 echo `seq -s "+" "10"`=`seq -s "+" "10"|bc` echo `seq -s "+" "10"`=`seq -s "+" "10"|xargs expr` 1+2+3+4+5+6+7+8+9+10=55 # 整型变量自增 加1的几种方法 a=1 a=$(($a+1)) a=$[$a+1] a=`expr $a + 1` let a++ ((a++))
10.函数后接的参数说明
a.shell的位置参数($1、$2、$#、$*、$?)都可以是函数的参数;
b.$0比较特殊,仍然是父脚本的名称;
c.在函数中return功能跟exit类似,作用是跳出函数;
d.在函数中使用exit会退出整个shell脚本,而不是退出函数;
e.return会返回一个退出值给调用函数的程序;
11.for循环
# C语言型的for循环 for((i=1;i<=5;i++)) do echo $i done for i in {1..5} for i in `seq 5` # 5到1的倒序,tac也可以实现倒序 seq 5 -1 1 seq 10 > a.log # 想要四个一行排列,下列方法哪一种更专业,当然是第二种 cat a.log | xargs -n4 xargs -n4 < a.log
12.break continue exit return对比
break:n表示跳出循环的层数,省略n表示跳出整个循环;
continue:忽略本次循环,进入下一次循环;
exit n:退出当前shell程序,n为返回值;
return n:用于函数中,n是函数的返回值,用于判断函数执行是否正确.
13.数组
数组就是各种数据类型的元素按一定顺序排列的集合.
# 计算数组的长度 arry=(1 2 3) echo ${#arry[*]} echo ${#arry[@]} # shell数组的下标从零开始 echo ${arry[0]} # 查看第一个元素 echo ${arry[*]} # 查看所有元素 # 增加元素或删除元素,截取和替换(略) arry[3]=4 unset arry[0] # 动态数组,将命令执行结果放到数组中 cc=(`ls`) cc=($(ls))
14.shell脚本调试总结
a.首先对dos2unix对脚本格式化;
b.直接执行脚本根据报错来调试;
c.sh -x调试脚本,显示执行过程(范围较大);
d.set -x和set +x调试部分脚本;
e.echo输出变量及相关内容,紧跟着exit退出:exit $var;exit
f.最关键的还是语法熟练、编码习惯、编程思想,将错误扼杀在萌芽,提高效率.
15.linux信号机制(常用1、2、3、15、20)
可以用kill -l或trap -l列出所有信号,常用信号说明
HUP(1):挂起,通常因终端掉线或用户退出(logout)而引发; INT(2):中断,通常因按下Ctrl+C组合键而引发; QUIT(3):退出,通常因按下Ctrl+/组合键而引发; ABRT(6):中止,通常因某些严重的执行错误(程序bug或命令执行出错)而引发; ALRM(14):报警,通常来处理超时; TERM(15):终止,通常在系统关机时发送; TSTP(20):停止进程的运行,但该信号可以被处理和忽略. 用户键入SUSP字符时(通常是Ctrl+Z)发出这个信号. stty -a # 列出键盘组合键对应的信号 trap -p # 把当前的trap设置打印出来 trap "" signals # 让某个信号失效 trap "commands" signals # 收到signals指定的信号时,信号功能复位同时执行commands命令 trap "ls" 2 # 每次执行Ctrl+C都会跟着执行ls命令 trap signals # 没有命令,只跟了个信号时,信号复原 trap "" 1 2 3 15 20 # 等价用于trap "" HUP INT QUIT TERM TSTP trap ":" HUP INT QUIT TERM TSTP 冒号:没什么影响,这个内置命令也什么都不做,可以作为Exit Status:Always succeeds
CentOS版本的发行注记
https://wiki.centos.org/zh/Manuals/ReleaseNotes/
https://blog.csdn.net/zhangmingcai/article/details/85341063