文章目录
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 fd
fd表示的文件描述符是否已经打开且与某终端相关
- 双目测试:
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|bcd
abc或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 许可协议。转载请注明出处!