内容摘要
- shell脚本介绍
- shell脚本结构和执行
- date命令用法
- shell脚本中的变量
- shell脚本中的逻辑判断
- 文件目录属性判断
- if特殊用法
- case判断
- for循环
- while循环
- break跳出循环
- continue结束本次循环
- exit退出整个脚本
一、Shell脚本介绍
- shell是一种脚本语言
- 可以使用逻辑判断、循环等语法
- 可以自定义函数
- shell是系统命令的集合
- shell脚本可以实现自动化运维,能大大增加我们的运维效率
二、shell脚本结构和执行方法
- 开头需要加#!/bin/bash
- 以#开头的行作为解释说明
- 脚本的名字以.sh结尾,用于区分这是一个shell脚本
- 执行方法有两种:
- chmod a+x sh; ./1.sh
- bash 1.sh
- 查看脚本执行过程: bash -x 1.sh
- 查看脚本是否语法错误: bash -n 1.sh
- 其中/bin/sh就时/bin/bash,它们之间做了软链接
三、date命令用法
date 可以用来显示或设定系统的日期与时间。
命令 | 含义 | 示例(2018年10月21日为例) |
date +%Y | 年(4位) | 2018 |
date +%y | 年(2位) | 18 |
date +%m | 月 | 10 |
date +%d | 日 | 21 |
date +%D | 以 月/日/年 格式显示日期 | 10/21/18 |
date +%F | 以 年-月-日 格式显示日期 | 2018-10-21 |
date +%H | 小时 | 21 |
date +%M | 分钟 | 18 |
date +%S | 秒 | 45 |
date +%T | 以时:分:秒 格式显示时间 等于 date +%H:%M:%S | 21:18:52 |
date +%s | 时间戳 表示距离1970年1月1日到现的秒数 | 1540127947 |
date +%w | 这个星期的第几天 | 0 |
date +%W | 今年的第几周 | 42 |
date +%h | 月份缩写 等于 date +%b | 10月 |
date -d "-1 day" | 一天前 | 2018年 10月 20日 星期六 21:22:07 CST |
date -d "+1 day" | 一天后 | 2018年 10月 22日 星期一 21:23:11 CST |
date -d "-1 year" | 一年前 | 2017年 10月 21日 星期六 21:23:26 CST |
date -d "-1 month" | 一个月前 | 2018年 09月 21日 星期五 21:23:34 CST |
date -d "-1 hour" | 一小时前 | 2018年 10月 21日 星期日 20:24:04 CST |
date -d "-1 min" | 一分钟前 | 2018年 10月 21日 星期日 21:23:13 CST |
- 将指定的时间转换为时间戳:date +%s -d "2018/10/21 21:31:00"
- 将指定的时间戳转换为时间:date -d @1540051200 +%F
四、shell脚本中的变量
- 当脚本中使用某个字符串较频繁并且字符串长度很长时就应该使用变量代替
- 使用条件语句时,常使用变量 if [ $a -gt 1 ]; then ... ; fi
- 引用某个命令的结果时,用变量替代 n=`wc -l 1.txt`
- 写和用户交互的脚本时,变量也是必不可少的 read -p "Input a number: " n; echo $n 如果没写这个n,可以直接使用$REPLY
- 内置变量 $0, $1, $2… $0表示脚本本身,$1 第一个参数,$2 第二个 .... $#表示参数个数
- 数学运算a=1;b=2; c=$(($a+$b))或者$[$a+$b]
五、 Shell脚本中的逻辑判断
#!/bin/bash
a=5
if [ $a -gt 3 ]
then
echo ok
fi
- 其中方括号内开头结尾必须要有空格
- -gt表示大于
- 在命令行中可以写成:a=5;if [ $a -gt 3 ];then echo ok;fi
- 格式2:if 条件; then 语句; else 语句; fi
#!/bin/bash
a=4
if [ $a -lt 3 ]
then
echo yes
else
echo no
fi
- -lt表示小于
- 其中else表示不符合条件时打印的语句
- 格式3:if 条件1; then 语句1;elif 条件2; then 语句2; elif条件3;then 语句3;else 语句3; fi
#!/bin/bash
a=5
if [ $a -eq 3 ]
then
echo "the num = 3"
elif [ $a -gt 6 ]
then
echo "the num > 6"
elif [ $a -lt 4 ]
then
echo "the num < 4"
else
echo "the num = 5"
fi
- 意思为符合条件1则执行语句1,不符合则再判断是否符合条件2,再不符合则判断条件3,都不符合则执行语句else
- 其中eq表示等于
- elif条件可以写多个
- 逻辑判断表达式:if [ $a -gt $b ] if [ $a -lt 5 ] if [ $b -eq 10 ]
- 也可以使用数学形式 if (($a>$b)) if(($a<5)) if(($b==10))
参数 | 数学符号 | 含义 |
-gt | > | 大于(greater than) |
-lt | < | 小于 (less than) |
-eq | == | 等于(equal) |
-ge | >= | 大于等于 |
-le | <= | 小于等于 |
-ne | != | 不等于 |
- 表示并且,同时满足:if [ $a -gt 5 ] && [ $a -lt 10 ]
- 表示或者满足其中一个: if [ $b -gt 5 ] || [ $b -lt 3 ]
六、文件目录属性判断
参数 | 含义 |
[ -f file ] | 判断是否是普通文件,且存在 |
[ -d file ] | 判断是否是目录,且存在 |
[ -e file ] | 判断文件或目录是否存在 |
[ -r file ] | 以当前用户来判断文件是否可读 |
[ -w file ] | 以当前用户来判断文件是否可写 |
[ -x file ] | 以当前用户来判断文件是否可执行 |
#!/bin/bash
f="/tmp/aminglinux"
if [ -f $f ]
then
echo $f exist
else
touch $f
fi
#!/bin/bash
f="/tmp/aminglinux"
if [ -d $f ]
then
echo $f exist
else
touch $f
fi
#!/bin/bash
f="/tmp/test"
[ -f $f ] && rm -f $f
- 判断是否是文件,是的话删除该文件。
- [ -f $f ] || rm -f $f 它表示文件不存在则执行rm语句 等同于[ ! -f $f ] && rm -f $f
- 它与下面的代码是一样的意思:
#!/bin/bash
f="/tmp/test"
if [ -f $f ]
then
rm -f $f
fi
#!/bin/bash
f="/tmp/test"
if [ -e $f ]
then
touch $f
fi
- 即使已经存在了也会去touch该文件但会更改文件/目录的是时间
#!/bin/bash
f="/tmp/test"
if [ -r $f ]
then
echo "$f readable"
fi
七、if特殊用法
参数 | 含义 |
[ -z “$a” ] | 表示当变量a的值为空 |
[ -n “$a” ] | 表示当变量a的值不为空 |
- 使用命令来做判断条件:if grep -wq zhaoyujie /etc/passwd;then echo zhaoyujie exist;fi
- 判断zhaoyujie用户是否存在,存在则输出zhaoyujie exist
- 其中grep -wq 表示选取(-w)过滤完全符合的一个词(-q)不打印
- 使用! 在参数前 表示取反 [ ! -e file ] 表示文件不存在
- if (($a<1)); then …等同于 if [ $a -lt 1 ]; then…
- 中括号中不能使用<,>,==,!=,>=,<=这样的符号
八、case判断
case 变量名 in
value1)
command
;;
value2)
command
;;
*)
commond
;;
esac
- 在case程序中,可以在条件中使用|,表示或的意思, 比如:
2|3)
command
;;
#!/bin/bash
#让用户输入数字
read -p "Please input a number: " n
#判断用户是否没填数字
if [ -z "$n" ]
then
echo "Please input a number."
exit 1
fi
#判断用户是否填写了数字以外的字符
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "Please input a number."
exit 1
fi
#把分数赋值给tag
if [ $n -lt 60 ] && [ $n -ge 0 ]
then
tag=1
elif [ $n -ge 60 ] && [ $n -lt 80 ]
then
tag=2
elif [ $n -ge 80 ] && [ $n -lt 90 ]
then
tag=3
elif [ $n -ge 90 ] && [ $n -le 100 ]
then
tag=4
else
tag=0
fi
case $tag in
1)
echo "不合格"
;;
2)
echo "合格"
;;
3)
echo "良好"
;;
4)
echo "优秀"
;;
*)
echo "The number range is 0-100."
;;
esac
九、for循环
- 语法:for 变量名 in 条件; do …; done
- 计算出0到100的总和:
#!/bin/bash
sum=0
for i in `seq 1 100`
do
sum=$[$sum+$i]
done
echo $sum
#!/bin/bash
cd /etc/
for a in `ls /etc/`
do
[ -d $a ] && ls $a
done
- for循环是以空格作为分隔符 ,因此文件名中带有空格时需要注意,出现显示错误的情况:for循环把3 4.txt 分为了两个文件
十、while循环
- 语法:while 条件; do … ; done
- 需求:每隔30秒查看系统负载,当大于10时发邮件
- 在while中 : ture 1 都是代表为正 因此while true 就是一个死循环
- 为了不让while脚本意外终止,可以使用screen命令执行此脚本
#!/bin/bash
while true
do
load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1`
if [ $load -gt 10 ]
then
top|mail -s "load is high: $load" asldkfls@11.com
fi
sleep 30
done
#!/bin/bash
while :
do
read -p "Please input a number: " n
if [ -z "$n" ]
then
echo "you need input sth."
continue
fi
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "you just only input numbers."
continue
fi
break
done
echo $n
十一、break跳出循环
break:跳出当前循环,也称结束当前循环
- 脚本:当$i等于3时跳出循环,不执行之后的循环,并且打印zhaoyujie:
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
break
fi
echo $i
done
echo zhaoyujie
十二、continue结束本次循环
- 忽略continue之下的代码,直接进行下一次循环
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 3 ]
then
continue
fi
echo $i
done
echo $i
十三、exit退出整个脚本
- exit会直接退出整个脚本
- exit后可以定义一个退出的数字,使用echo $? 查看该数字(用来判断退出状态)
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
exit 1
fi
echo $i
done
echo aaaa
- 匹配后直接退出脚本