Fork me on GitHub

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

 

posted @ 2019-05-17 11:24  法外狂徒  阅读(224)  评论(0编辑  收藏  举报