基础概念
什么是shell scripts
利用shell 的功能所写的一一个[程序(program)」,这个程序是使用纯文本文件,将- -些shell 的语法与指令(含外部指令)写在里面,搭配正规表示法、 管线命令与数据流重导向等功能,以达到我们所想要的处理目的。
shell scripts注意事项
- 指令的执行是从上而下,从左至右的分析与执行
- 指令、选项、参数之间的多个空白都会被忽略掉,空白行也将被忽略,并且tab键推开的空白同样视为空白键
- 如果读取到一个enter符号(CR),就开始执行该行命令
- 如果一行内容太多可以使用 \enter 来延申到下一行
- #可作为批注,#后面的内容将全部视为批注而在执行中被忽略
如何执行shell scripts
直接指令下达:shell.sh必须具备可读与可执行权限,然后
- 绝对路径:使用/home/shell.sh来下达指令
- 相对路径:如当前目录在/home,则使用 ./shell.sh执行
- 变量PATH:将shell.sh放入PATH指定的目录内
以bash程序执行:通过bash shell.sh 或 sh shell.sh来执行
不同执行方式的差异
关键:当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回父程序中
标准shell scripts结构
- 第一行 #!/bin/bash 宣告这个scripts使用的shell名称
- 程序内容的说明
- 主要环境变量的宣告
- 主要程序部分
- 执行成果告知(定义传回值)
撰写习惯
- 脚本功能
- 脚本版本信息
- 脚本作者
- 脚本版权宣告
- 脚本历史记录
- 脚本内特殊的指令,使用绝对路径
- 脚本需要的环境变量预先宣告与设定
预先定义脚本说明
[root@centos8 ~]#vim .vimrc
set ts=4
set expandtab
set ignorecase
set cursorline
set autoindent
set number
autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
if expand("%:e") == 'sh'
call setline(1,"#!/bin/bash")
call setline(2,"#********************************************************************")
call setline(3,"#FileName: ".expand("%"))
call setline(4,"#Version: 1.0")
call setline(5,"#Date: ".strftime("%Y-%m-%d"))
call setline(6,"#Author: wenzi")
call setline(7,"#Description: This is description")
call setline(8,"#********************************************************************")
call setline(9,"")
endif
endfunc
autocmd BufNewFile * normal G
shell scripts的debug
sh [选项] test.sh
-n:不执行 .sh 文件,仅检查语法
-v:执行 .sh 文件前,先将 .sh 内容输出到屏幕上
-x:将使用到的scripts内容输出到屏幕上
shell scripts变量
见 认识与学习Bash-CSDN博客变量部分
shell scripts语法
算术运算
实现方式
- let var=算术表达式
- ((var=算术表达式))
- var=$[算术表达式]
- var=$((算术表达式))
- var=$(expr arg1arg2 arg3 ...)
- declare -i var = 数值
- echo '算术表达式' | bc
增强型赋值
格式:let 算术表达式
#!/bin/bash
num=1
sum=0
while [ $num -lt 3 ];do
sum=$[$sum+$num]
let num++
done
echo "$sum"
结果为 3 ,注意是 let num++ 而不是 let $num++
+= i+=10 相当于 i=i+10
-= i-=j 相当于 i=i-j
++ i++ 相当于 i=i+1
-- i-- 相当于 i=i-1
内建的随机数生成器变量:$RANDOM 取值范围:0-32767
在Shell中,以0开头的数字被解释为八进制数,使用会出现报错或计算出错
[root@wenzi wenzi]# echo $[1+010]
9
[root@wenzi wenzi]# echo $[1+09]
-bash: 1+09: value too great for base (error token is "09")
判断式
test 【选项】 【参数】
关于某个档名的文件类型判断,如 test -e filename
- -e 该档名是否存在
- -f 该档名是否存在且为文件
- -d 该档名是否存在且为目录
- -b 该档名是否存在且为一个块设备
- -c 该档名是否存在且为一个字符设备
- -S 该档名是否存在且为一个socket文件
- -p 该档名是否存在且为一个FIFO文件
- -L 该档名是否存在且为一个链接文件
关于某个文件的权限检测,如 test -r filename
- -r 检测该文件名是否存在且具有 读read 权限
- -w 检测该文件名是否存在且具有 写write 权限
- -x 检测该文件名是否存在且具有 执行x 权限
- -u 检测该文件名是否存在且具有 SUID 属性
- -g 检测该文件名是否存在且具有 SGID 属性
- -k 检测该文件名是否存在且具有 Sticky bit 属性
- -s 检测该文件名是否存在且为非空白文件
关于两个文件之间的比较,如 test file1 -nt file2
- -nt 判断file1是否比file2新;new than
- -ot 判断file1是否比file2旧;old than
- -ef 判断file1、file2是否为同一文件,可用于判断硬链接上,主要值两个文件是否均指向同一个inode
关于两个整数之间的比较,如 test n1 -eq n2
- -eq 两值相等
- -ne 两值不等
- -gt n1大于n2
- -lt n1小于n2
- -ge n1大于等于n2
- -le n1小于等于n2
关于字符串的判定
- test -z string 判定字符串是否为0,若string为空字符串,则为true
- test -n string 判定字符串是否为非0,若string为空字符串,则为false
- test str1 == str2 判定str1是否等于str2,若相等,则传回true
- test str1 != str2 判定str1是否不等于str2,若相等,则传回false
多重条件判定,如 test -r filename -a -w filename
- -a 即且的关系,两者同时成立才传回true;test -r filename1 -a -w filename1,若filename1同时具有read和write权限才传回true
- -o 即或的关系,两者任意一个成立就传回true;test -r filename2 -o -w filename2,若filename2具有read或write权限就传回true
- ! 相反状态;test ! -x filename3 ,当filename3不具有执行权限时,则传回true
利用判断符号[]
想知道${HOME}这个变量是否为空时,可以 [ -z “${HOME}” ];echo $?
注意:因为中括号用在很多地方,包括通配符和正则表达式等,所以在bash语法中使用[]时,中括号内的两端需要有空格
中括号内的每个组件都需要有空格键来分割;中括号内的变量,最好用双引号;中括号内的常数,最好用双引号或单引号
可用 && 或 || 符号代替 -a 或 -o
[[ expression ]] 用法
- == 左侧字符串是否和右侧的PATTERN相同
注意:此表达式用于[[ ]]中,PATTERN为通配符。若不想使用通配符*,只想表达*本身,可以用" "引起来或转义符\
- =~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
注意: 此表达式用于[[ ]]中;扩展的正则表达式
语法
if...then
if [ 条件判断式 ];then
当条件判断式成立时,执行此处内容
fi
if [ 条件判断式 ];then
当条件判断成立时,执行此处内容
else
当条件判断不成立时,执行此处内容
fi
if [ 条件判断式1 ];then
当条件判断1成立时,执行此处内容
elif [ 条件判断式2 ];then
当条件判断2成立时,执行此处内容
else
当条件判断1和2都不成立时,执行此处内容
fi
case...in
其中 case $变量 in 中,$变量 通过两种方法赋值
- 直接下达式:bash test.sh 参数 直接给予$1内容
- 交互式:通过read让用户输入变量
case $变量名称 in
“第一个变量内容”)
程序语句
;;
“第二个变量内容”)
程序语句
;;
*)
不包含第一个、第二个变量内容的其他程序语句
;;
esac
function fname() {}
由于程序执行顺序,函数的定义要在程序最前面
写法一:
func_name () {
程序语句
}
写法二:
function func_name {
程序语句
}
写法三:
function func_name () {
程序语句
}
while...do
当判断式条件成立,就进行循环,直到条件不成立
while [ 判断式 ]
do
程序语句
done
while read LINE
逐行读取信息。LINE是变量名
cat a.txt | while read LINE; do
echo $LINE
donewhile read line;do
循环体
done < 文件绝对路径
until...do
当判断式条件成立时,就停止循环,否则就继续循环
until [ ]
do
程序语句
done
for
for var in con1 con2 con3 …
do
程序语句
done
以上语句,第一次循环时,$var内容为con1;第二次循环时,$var内容为con2;第三次循环时,$var内容为con3;…
for ((初始值;限制值;执行语句))
do
程序语句
done
select
select语句用于创建基于用户输入的菜单
- item是一个变量,用于存储用户从菜单中选择的值。
- list是一个包含供用户选择的可选项的列表。
select item in list
do
执行语句
done
#!/bin/bash
PS3="请选择选项:"
options=("选项1" "选项2" "选项3" "退出")
select opt in "${options[@]}"
do
echo "您选择了 $opt"
case $opt in
"选项1")
echo "执行选项1的操作"
;;
"选项2")
echo "执行选项2的操作"
;;
"选项3")
echo "执行选项3的操作"
;;
"退出")
break
;;
*)
echo "无效的选择"
;;
esac
done