文章目录
shell编程
- 所有的shell文件都是以 .sh 结尾。
- 执行方式:
方式1
chmod +x test.sh
./test.sh
方式2
sh test.sh
shell基础(首行 #!/bin/sh)
变量赋值
- 变量名=值
注意 := 两侧不能有空格:name="张三丰"
- 赋值方式
直接赋值 :x=10 y=20
获取命令的执行结果给变量赋值
1、time=$(date)
2、time=`date`
3、接收从键盘输入的字符给变量赋值:read -p "提示信息" -t 5 变量名
- 输出语句
echo $变量名
- ‘’ 和 “” 的区别
1、’’ 无法获取变量的值(所见即所得)
2、"" 可以获取变量的值(解析变量)
read -p "请输入姓名:" -t 5 name(-t 5 五秒退出)·
echo '变量$name的值是:'$name
- 撤销变量
unset 变量名 - 环境的相关文件
.bash*
环境变量
- 临时变量:只对当前shell生效;
- 全局变量: export对所有shell生效 ;
- 永久环境变量:写入/etc/profile文件。
重要的特殊位置变量
- $0 脚本的名称
- $n 脚本的第一个参数
- $# 传参的总个数
案例:[ $# -ne 2] && echo “请输入2个参数” && exit - $*
- $@
- ∗ 和 *和 ∗和@一般情况下没有差别,只有再循环体内有差异
- $? 获取上一条命令的结果 0为成功,非0失败
- $$ 获取脚本的PID
- $! 获取上一条后台脚本的PID
- $_ 获取脚本的最后一个参数
传参的三种形式
-
直接传参
-
赋值传参
-
read传参
-
示例
案例一:使用read传参的方式更改系统的主机名称和IP地址的最后一位。
案例二:#!/bin/sh url=$1 ping -c 1 -W 1 $url >/dev/null 2>&1 #-c ping的次数 -W时间 2标准错误 1标准输出 [ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"
-
字符串
echo $name|wc -L
统计变量的长度
echo ${#name}
统计变量的长度
echo $name|awk '{print $2}'
打印输出的第二个字符串
echo $name|awk -F "[m]" '{print $2}'
以m为分隔,打印输出的第二个字符串字
echo \${name:2:2}
切片:从第二个字符之后,向后取2个案例:取字符串长度小于3的 expr length "$name" echo $name|awk '{print length}' 方法一: for i in I am mabaoguo teacher I am 18. do [ ${#i} -lt 3 ] && echo $i done 方法二: echo I am lizhenya teacher I am 18.|xargs -n1|awk '{if(length<3)print}' (-n1 以空格分为1列) 方法三: echo I am lizhenya teacher I am 18.|awk '{for(i=1;i<NF;i++)if(length($i)<3)print $i}'
变量的删除和替换
- 变量的删除
echo ${url#*.}
url变量不变,从前往后删除,结果为com.cn
sina.com.cn
echo ${url%.*}
url变量不变,从后往前删除,结果为www.sina
www.sina.com - 变量的替换
echo ${url/sina/baidu}
www.baidu.com.cn
echo ${url//w/m}
贪婪匹配
mmm.sina.com.cn
运算符
算术运算符
- 算术运算符
+ - * / %
++ : 自加1运算,类似于python中 i++ 等同于 i+=1
– : 同++
运算命令
- let 运算表达式(常用)
i=1
let i++
echo $i - expr 运算表达式(只支持整数运算)
i=1
sum=`expr $i + 5` # +两侧要有空格
echo $sum - $(())
echo $((10*10))
100 - $[]
echo $[10+10]
20 - bc
- awk ‘BEGIN{print 10+10}’
echo 100 200|awk ‘{print $1+$2}’ - 举例:
ps axuf|awk '{print $5}'|grep -v VSZ|tr "\n" "+"|sed -r 's#(.*)#\10\n#g'|bc
ps axuf|awk '{print $5}'|grep -v VSZ|awk '{sum += $1}END{print sum}'
比较运算符(man test)
-
文件状态
-e :文件/目录是否存在
-d : 判断是否为目录
-f : 判断是否为文件 -
字符比较
= 、!=
空 :-z 字符串长度为0,则为真
非空 :!-z 或者 -n -
数值比较
等于 :-eq
大于 :-gt
>= :-ge
< :-lt
<= :-le
不等于:-ne -
逻辑比较
逻辑与 :&& python中and
逻辑或 :|| python中or案例一: free=`free|awk 'NR==2{print $3/$2*100}'` [ ${free%.*} -gt 10 ] && echo error || error ok 案例二: [ `df -h|grep /$|awk -F "[ %]+" '{print $(NF-1)}'` -gt 5 ] && echo error || echo ok
-
正则的比对[[]]
age=1.2 [[ "$age" =~ ^[0-9]+$ ]] echo $? 0
-
多整数比对
-a 并且 [ 10 -eq 10 -a 100 -eq 100 ] echo $? 0 -o 或者 [ 10 -eq 10 -a 10 -eq 100 ] echo $? 0 案例一: [ $# -ne 2 ] && echo "please input two number" && exit [[ ! $1 =~ ^[0-9]+$ ]] && echo "please input two number" && exit 50 [[ ! $2 =~ ^[0-9]+$ ]] && echo "please input two number" && exit 100 [ $1 -eq $2 ] && echo "$1=$2" [ $1 -lt $2 ] && echo "$1<$2" [ $1 -gt $2 ] && echo "$1>$2" 案例二:批量创建10个用户,要求密码统一设置为123456 案例三:判断当前10.0.0.0/24网络中,有哪些IP地址在线
-
[ ]用法
[ ]相等于test
案例:test -d test1 || mkdir test1
[ -f filename ] 文件存在
案例:[ -f test.sh ] && . test.sh
[ -d dir ] 目录为存在
案例:[ -d test ] || mkdir test 判读有无目录,无则创建
if条件判断
-
语法格式
if [ 条件判断 ];then ## 条件判断两侧要加 空格 执行语句 fi
-
多分支
if [ 条件判断 ];then 执行语句 elif [ ];then 执行语句 ... else 执行语句 fi
-
输入两个数字,比较大小
#!/bin/bash read -p "请输入第一个数字:" num1 read -p "请输入第二个数字:" num2 if [ $num1 -gt $num2 ];then echo "$num1>$num2" elif [ $num1 -lt $num2 ];then echo "$num1<$num2" else echo "$num1=$num2" fi
for循环
-
语法格式
for 变量名 in 值列表 do 执行语句 done
-
造数方法 seq 起始值 步长 终止值
seq 5 --> 1 2 3 4 5 seq 1 2 10 --> 1 3 5 7 9 seq 2 2 10 --> 2 4 6 8 10
C-for循环
-
语法格式
for ((赋初值;条件判断;步长)) do 执行语句 done
-
输出1-5之间的整数
#!/bin/bash for ((i=1;i<=5;i++)) do echo $i done
-
输出20-47之间的偶数
#!/bin/bash for((i=20;i<=47;i++)) do if [ `expr $i % 2` -eq 0 ];then echo $i fi done