文章目录
shell脚本基础
变量
变量名称注意事项
- 只能包含字母、数字、下划线,并且不能以数字开头
- 不应该跟系统中已有的环境变量重名,尽量不要全部使用大写,尽量不要用“_”下划线开头
- 最好做到见名知义
- 不能使用程序中的保留字,例如
if、for等
变量类型
- 字符型
- 数值型
- 整型
- 浮点型
- 布尔型
bash变量类型
环境变量
export VAR_NAME=VALUE //作用域为当前shell进程及其子进程
本地变量(局部变量)
VAR_NAME=VALUE //本地变量,作用域为当前shell进程
local VAR_NAME=VALUE //局部变量,作用域为当前代码段,常用于函数
位置变量
$1,$2,$3 //用来引用脚本的参数
shift [num] //位置变量使用完以后退出,后面的参数向前推进
特殊变量
- bash内置的,用来保存某些特殊数据的变量,也称系统变量
- 常用:
$?是显示上条命令的退出状态,0表示没有错误,其他表示有错误$#是传给脚本的参数个数$0是脚本本身的名字$!是shell最后运行的后台Process的PID$@是传给脚本的所有参数的列表$*是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个$$是脚本运行的当前进程ID号
bash内建环境变量
PATH执行命令的定义变量SHELL当前使用的shellUID当前用户的UIDHISTSIZE命令历史长度HOME当前用户家目录PWD当前工作目录HISTFILE历史命令记录的文件PS1定义命令提示符前的用户名主机名等
只读变量(常量)
readonly VAR_NAME=VALUE //不能修改值,只能等shell进程终止时随之消亡
脚本基础
程序返回值
- 程序执行以后有两类返回值:
- 程序执行的结果
- 程序状态返回代码(0-255)
- 0:正确执行
- 1-255:错误执行,1、2、127系统预留,有特殊意义
脚本测试
bash -n scriptname //检查脚本是否有语法错误
bash -x scriptname //单步执行,检查脚本错在哪里
写脚本注意事项
- 禁止将未成功执行过的代码直接写进脚本
- 脚本中的命令一定要用绝对路径
shell算数运算
A=3 //定义A变量值为3
B=6 //定义B变量值为6
let C=$A+$B //let 算术运算表达式
C=$[$A+$B] //$[算术运算表达式]
C=$(($A+$B)) //$((算术运算表达式))
C=$A+$B //算数加法
C=$[$A-$B] //算数减法
C==$[$A*$B] //算数乘法
C=$(printf "%.2f" `echo "scale=2;$1/$2"|bc`) //算数除法,保留各位的0
命令间的逻辑关系
- 逻辑与:&&
- 第一个条件为假时,第二个条件不用再判断,最终结果已经有
- 第一个条件为真时,第二个条件必须得判断
- 逻辑或:||
- 前一个命令的结果为真时,第二个命令就不执行
- 前一个命令的结果为假时,第二个命令必须执行
shell脚本进阶
bash条件判断
条件测试的表达式
[ expression ] //建议使用
[[ expression ]] //可以使用
test expression //不建议使用
整数测试
-eq测试两个整数是否相等-ne测试两个整数是否不等-gt测试一个数是否大于另一个数-lt测试一个数是否小于另一个数-ge大于或等于-le小于或等于
字符测试
== //等值比较,检查==两边的内容是否一致,==两边都要有空格
!= //检查两边内容是否不一致,不一致为真,一致为假
=~ //左侧字符串是否能够被右侧的PATTERN所匹配到。此表达式应用于双中括号[[]]中
-z "string" //测试指定字符串是否为空,空则为真,不空则为假
-n "string" //测试指定字符串是否不空,不空则为真,空则为假
文件测试
- 存在性测试:
-e测试文件是否存在
- 存在性及类别测试
- 常用:
-f测试文件是否为普通文件-d测试指定路径是否为目录
- 不常用
-b测试文件是否为块设备文件-c测试文件是否为字符设备文件-h测试文件是否为符号链接文件-L测试文件是否为符号链接文件-p测试文件是否为命名管道文件-S测试文件是否为套接字文件
- 文件权限测试:
-r测试当前用户对指定文件是否有读权限-w测试当前用户对指定文件是否有写权限-x测试当前用户对指定文件是否有执行权限
- 文件特殊权限测试:
-g测试文件是否有sgid权限-u测试文件是否有suid权限-k测试文件是否有sticky权限
- 文件大小测试:
-s测试文件是否非空
- 文件是否打开测试:
-t fdfd表示的文件描述符是否已经打开且与某终端相关
- 双目测试:
file1 -ef file2测试file1与file2是否指向同一个设备上的相同inode,说白点就是两者是不是同一个文件file1 -nt file2测试file1是否比file2新file1 -ot file2测试file1是否比file2旧
- 无分类:
-N测试文件自从上一次被读取之后是否被修改过-O测试文件是否存在并且被当前用户拥有-G测试文件是否存在并且默认组是否为当前用户组
组合测试条件
-a与关系,作用与&&相同-o或关系,作用与||相同!非关系
传入参数的个数大于1个,小于等于3个
[ $# -gt 1 -a $# -le 3 ]
[ $# -gt 1 ] && [ $# -le 3 ]
条件判断,控制结构
单分支if语句
if [ -f abc ]; then
echo "hello woeld"
......
fi
双分支if语句
if [ -f abc ]; then
echo "hello woeld"
else
echo "此文件不存在"
fi
多分支if语句
if [ $i -gt 5 ]; then
echo "大于5的数"
elif [ $i -lt 3 ]; then
echo "小于3的数"
else
echo "大于等于3,小于等于5的数"
fi
分支选择
case $1 in
'start')
/usr/local/httpd/bin/apachectl start
;;
'stop')
/usr/local/httpd/bin/apachectl stop
;;
'restart')
/usr/local/httpd/bin/apachectl restart
;;
'status')
status=$(ps -ef | grep -Ev "grep|$0|service httpd status"|grep httpd | wc -l)
if [ $status -ne 0 ];then
echo "httpd is running"
else
echo "httpd is stopped"
fi
;;
*)
echo "Usage:service $0 start|stop|status"
;;
esac
- case支持glob风格的通配符:
*任意长度任意字符?任意单个字符[]指字范围内的任意单个字符abc|bcdabc或bcd
在RHCE中会有一道脚本的考试题目,很简单,就是使用case语句。而且为了防止我们在做服务的时候,重启之后客户机无法挂在,通常会写一个自动挂载的脚本,与上面的代码相似。
循环语句
- 循环语句通常需要有一个进入条件和一个退出条件
for循环
- for循环当列表不为空时进入循环,否则退出循环
for (( expr1 ; expr2 ; expr3 ));do
循环体
done
for ((expr1;expr2;expr3))
{
循环体
}
for i in $(seq 1 2 100); do //i从后面的列表中取,1-100每隔2个数取一个数
echo $i
done
for ((i=0;i<=3;i++))
{
echo $i
}
for (( i=0;i<=3;i++ ));do
echo $i
done
- expr1 //用于指定初始条件,给控制变量一个初始值
- expr2 //判定什么时候退出循环
- expr3 //修正expr1指定的变量的值
- 如何生成列表:
- {1…100}
- seq [起始数] [步进长度] 结束数
while循环
- while循环适用于循环次数未知的场景,注意要有退出条件。
- 条件满足时进入循环,条件不满足了退出循环
- while循环正常用法
while 条件; do
statement
...
done
- while循环特殊用法
- while循环特殊用法一:死循环
while :;do //这里的冒号可以改成任何非空值
statement
...
done
- while循环特殊用法二:逐行读取某文件,将值存入line变量中
while read line;do
statement
...
done < /path/to/somefile
condition表示判断条件statements表示要执行的语句(可以只有一条,也可以有多条),do和done都是 Shell中的关键字while循环的执行流程为:
- 先对
condition进行判断,如果该条件成立,就进入循环,执行while循环体中的语句,也就是do和done之间的语句。这样就完成了一次循环。- 每一次执行到
done的时候都会重新判断condition是否成立,如果成立,就进入下一次循环,继续执行do和done之间的语句,如果不成立,就结束整个while循环,执行done后面的其它 Shell代码。- 如果一开始
condition就不成立,那么程序就不会进入循环体,do和done之间的语句就没有执行的机会。
until循环
- 条件不满足时进入循环,条件满足了退出循环
until 条件; do
statement
...
done
[root@bad test]# vim 1.sh
#!/bin/bash
until [ 4 -eq 5 ] //4等于5不满足,进入循环
do
echo "hello"
break
done
[root@RedHat test]# bash 1.sh
hello
循环语句特殊情况
- 在循环语句中,有几种特别情况:
break [num] //提前退出循环。当循环语句中出现break时,将提前退出循环,不再执行循环后面的语句
continue [num] //提前结束本轮循环而进入下一轮循环。当循环语句执行到continue时,continue后面的语句将不再执行,提前进入下一轮循环
break //命令用于跳出循环,使用break可以跳出任何类型的循环:for、while、until
continue //命令用于中止本次循环,重新判断循环条件,开始下一次循环。
exit //退出脚本
定义脚本退出状态码
- exit命令用于定义执行状态结果
exit #此处的#号是一个数字,其范围可以是0-255
- 如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码
- 注意:脚本中一旦遇到exit命令,脚本会立即终止
以上内容均属原创,如有不详或错误,敬请指出。
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!