### shell脚本进阶
选择执行:
```
1、 if 条件 ;then
等于
if 条件
then
fi
2、 if 条件 ;then
ture的分支代码
else
false的分支代码
fi
3、 if 条件1 ;then
条件1的分支
elif 条件2 ;then
条件2分支
elif 条件3 ;then
条件分支3
......
else
非条件[123]的分支
fi
备注:条件是用命令的执行状态结果判断
成功:ture $?=0
失败:false $?=1
备注2:如果条件判断满足多个,则自上而下满足第一个条件就停止
```
case
case 变量引用 in
PAT1)
分支1
;;
PAT2)分支2
;;
......
*)
默认分支
;;
esac
备注:此处使用glob风格
#### 循环
循环执行
把某段代码重复运行多次
循环一般来讲都有进入条件和退出条件
for循环
for VarName in TAB ;do
循环体
done
执行机制:依次把TAB中的元素赋值给“变量名”,每次赋值后执行依次循环体,到TAB中的元素结束
列表的生成方式
(1)直接给出列表
(2)整数列表
seq
{#..#}
(3)命令调用生成列表
$(CMD)
`CMD`
(4)glob机制
(5)变量引用
while循环
whie CONDITION ;do
循环体
done
CONDITION:循环控制条件:进入循环之前先做一次判断,每一次循环之后会再次做判断,条件为ture则执行依次循环,直到调试状态为false循环终止
因此:CONDITION一般应该有循环控制变量:而此变量的值会在循环体中不断地被修改
umtil CONDITION ;DO
循环体
done
until 和while 相反,满足CONDITION时退出循环
无限循环:
while ture[:] ;do
循环体
done
或者
until false ;do
循环体
done
特殊用法
while read Line ;do
循环体
done < /PATH/FROM/SOMEFILE
依次读取SOMEFILE中的每一行 且把行赋值给Line变量
for循环特殊格式
for((控制变量初始化;条件判断表达式;控制变量的修正表达式));do
循环体
done
备注:此种循环中,双括号中的变量不需要加$。
function
function:实现代码重用
语法1、
function F_name{
...函数体...
}
语法2
F_name(){
...函数体...
}
调用:函数只有被调用才会执行
调用方法:给定函数名
函数名字出现的地方,会被自动替换为函数代码
函数是有生命周期的,被调用时被创建,返回时结束;
如果想人工返回需要调用return, 返回值0表示成功;1-255
表示失败,或者我们可以自己制定返回值。
执行return 后续的命令就不执行了
如果脚本中要调用脚本自身,则可以用 $0 表示
函数可以接受参数:
调用函数时,在函数名后边以空格为分隔符给定参数列表。
在函数体中可以使用$1 $2...调用这些参数,也可以用$@,$*$# 等用法
变量作用域:
本地变量:当前shell进程,为了执行脚本会启动专用的shell进程;因此,本地变量的作用范围为当前shell文件
局部变量:函数生命周期:函数结束时变了会被自动销毁,如果函数中有局部变量其名称同本地变量,
如果想只在函数中使用变量
用local 声明
函数递归:
函数直接或者间接的调用自己;
信号捕捉trap
语法:trap '' #
''中放的CMD是替换捕捉信号的CMD
如果什么都不加,表示对捕捉道德信号不作处理,相当于忽略
#可以用SIN名称代替
常用的有1 重读
9强行杀掉
15 正常退出
跳出循环
continue
表示跳出本次循环,继续执行下次循环
break n
表示退出本层循环
n表示基层循环
#### 数组:相当于多个变量(元素),的连续的内存空间
引用数组中的元素:${数组名【元素下标】}
声明数组 :declare -a 数组名
declare -A
数组名(关联数组)
关联数组不需要用数字定义也被称之为映射
bash shell 数组支持稀疏格式(1,2,6,7 指的是不连续的数字)
数组的赋值方式 :
1)一次只赋值一个元素:
数组名【下标】=VALUE
2)一次赋值全部元素:
数组名【下标】=(“ ” “ ” “ ” ....)
3只赋值特定元素:
数组名=(【下标】=VAL1 【下标2】=VAL2)
4)read -a 数组名
引用数组元素:
${数组名【下标】}
下标省略时,表示引用下标为0的元素
查看数组的元素个数 ${#数组名[*]} 或${#数组名[@]}
示例
declare -a log
log=(/var/log/*.log)
for i in `seq ${#log[*]}`;do
let i++
echo log[$i]=${log[$i]}
done
~
调用数组中的元素
${NAME[@]}
${NAME[*]}
${NAME[@]:#:#}
第一个#表示跳过几个元素
第二个表示要取出的元素个数
${Name[@]:#}
表示跳过几个元素其他的全部输出
向数组中追加元素的方法:
Name[${#Name[@]}]
删除数组中的元素
unset Name[下标]
关联数组
declare -A NAME
NAME=([I_NAME]="var1" [I_NAME2]="VAR2"...)
字符串处理工具
NAME=“var"
${NAME:#:#}
偏移几个取几个字符
[root@zhangxiao ~]#N=/var/systemd/helllo
[root@zhangxiao ~]#echo ${N:3:3}
[root@zhangxiao ~]#echo “${N:3:3}”
“r/s”
${Name: -#}
取右侧字符串的几个(空格后必须有空格)
#N=/var/systemd/helllo
[root@zhangxiao ~]#echo ${N: -7}
/helllo
基于模式取子串
${VAR#*WORD}
其中word可以是指定的任意字符;
功能:自左而右,查找VAR变量中存储的字符,第一次出现的word,删除字符串开头到第一次出现word字符之间所有的字符
echo ${N#*/}
var/systemd/helllo
${VAR##*WORD}
同上不过删除的是字符串开头至最后一次匹配到wprd单词的所有字符
echo ${N##*/}
helllo
${VAR%WORD*}
同上,从右向左匹配删除到第一次匹配到WORD
${VAR%%WORD*}
同上,匹配到最后一次
查找替换:
${NAME/PATTERN/替换的内容}
自左而右查找PATTERN匹配的内容,用内容替换
${NAME//PATTERN/替换的内容}
自左而右查找PATTERN匹配的内容,用内容替换所有
${Name/^Pattern/内容}
只替换行首的Pattern内容
${Name/%Pattern/内容}
只替换行首的Pattern内容
${Name/Pattern}
自左至右查找pattern中的内容 删除
${Name//Pattern}
自左至右查找pattern中的内容 全部删除
${Name/#Pattern}
自左至右查找pattern中的内容 删除至pattern
${Name/%Pattern}
自右至左查找pattern中的内容 删除至pattern
${VAR^^}:把VAR中的小写字母换成大写
${VAR,,}:把VAR中的大写字母换成小写
变量赋值
${VAR:-VAR2}
变量有值返回VAR,没有值返回VAR2
${VAR:=VAR2}
变量有值返回VAR,没有值返回VAR2,并把VAR2赋值给VAR
${VAR:+VAR2}
如果VAR不空,返回VAR2
${VAR:?VAR2}
为空则返回VAR2(VAR2一般是错误信息)
如何为脚本提供配置文件
在脚本中. 或者sorce后边最好跟绝对路径
mktemp
mktemp /temp/Name.XXX(最好用XXX)
(X最好要出现三次)
(X会替换成随机字母或者数字)
引用临时文件
tempfile=(/temp/test.XXX)
install 命令:
用法和cp命令一致
不过选项增加
-m:指明权限
-o:指明属主
-g指明属组
可以创建空目录并指定其权限
选择执行:
```
1、 if 条件 ;then
等于
if 条件
then
fi
2、 if 条件 ;then
ture的分支代码
else
false的分支代码
fi
3、 if 条件1 ;then
条件1的分支
elif 条件2 ;then
条件2分支
elif 条件3 ;then
条件分支3
......
else
非条件[123]的分支
fi
备注:条件是用命令的执行状态结果判断
成功:ture $?=0
失败:false $?=1
备注2:如果条件判断满足多个,则自上而下满足第一个条件就停止
```
case
case 变量引用 in
PAT1)
分支1
;;
PAT2)分支2
;;
......
*)
默认分支
;;
esac
备注:此处使用glob风格
#### 循环
循环执行
把某段代码重复运行多次
循环一般来讲都有进入条件和退出条件
for循环
for VarName in TAB ;do
循环体
done
执行机制:依次把TAB中的元素赋值给“变量名”,每次赋值后执行依次循环体,到TAB中的元素结束
列表的生成方式
(1)直接给出列表
(2)整数列表
seq
{#..#}
(3)命令调用生成列表
$(CMD)
`CMD`
(4)glob机制
(5)变量引用
while循环
whie CONDITION ;do
循环体
done
CONDITION:循环控制条件:进入循环之前先做一次判断,每一次循环之后会再次做判断,条件为ture则执行依次循环,直到调试状态为false循环终止
因此:CONDITION一般应该有循环控制变量:而此变量的值会在循环体中不断地被修改
umtil CONDITION ;DO
循环体
done
until 和while 相反,满足CONDITION时退出循环
无限循环:
while ture[:] ;do
循环体
done
或者
until false ;do
循环体
done
特殊用法
while read Line ;do
循环体
done < /PATH/FROM/SOMEFILE
依次读取SOMEFILE中的每一行 且把行赋值给Line变量
for循环特殊格式
for((控制变量初始化;条件判断表达式;控制变量的修正表达式));do
循环体
done
备注:此种循环中,双括号中的变量不需要加$。
function
function:实现代码重用
语法1、
function F_name{
...函数体...
}
语法2
F_name(){
...函数体...
}
调用:函数只有被调用才会执行
调用方法:给定函数名
函数名字出现的地方,会被自动替换为函数代码
函数是有生命周期的,被调用时被创建,返回时结束;
如果想人工返回需要调用return, 返回值0表示成功;1-255
表示失败,或者我们可以自己制定返回值。
执行return 后续的命令就不执行了
如果脚本中要调用脚本自身,则可以用 $0 表示
函数可以接受参数:
调用函数时,在函数名后边以空格为分隔符给定参数列表。
在函数体中可以使用$1 $2...调用这些参数,也可以用$@,$*$# 等用法
变量作用域:
本地变量:当前shell进程,为了执行脚本会启动专用的shell进程;因此,本地变量的作用范围为当前shell文件
局部变量:函数生命周期:函数结束时变了会被自动销毁,如果函数中有局部变量其名称同本地变量,
如果想只在函数中使用变量
用local 声明
函数递归:
函数直接或者间接的调用自己;
信号捕捉trap
语法:trap '' #
''中放的CMD是替换捕捉信号的CMD
如果什么都不加,表示对捕捉道德信号不作处理,相当于忽略
#可以用SIN名称代替
常用的有1 重读
9强行杀掉
15 正常退出
跳出循环
continue
表示跳出本次循环,继续执行下次循环
break n
表示退出本层循环
n表示基层循环
#### 数组:相当于多个变量(元素),的连续的内存空间
引用数组中的元素:${数组名【元素下标】}
声明数组 :declare -a 数组名
declare -A
数组名(关联数组)
关联数组不需要用数字定义也被称之为映射
bash shell 数组支持稀疏格式(1,2,6,7 指的是不连续的数字)
数组的赋值方式 :
1)一次只赋值一个元素:
数组名【下标】=VALUE
2)一次赋值全部元素:
数组名【下标】=(“ ” “ ” “ ” ....)
3只赋值特定元素:
数组名=(【下标】=VAL1 【下标2】=VAL2)
4)read -a 数组名
引用数组元素:
${数组名【下标】}
下标省略时,表示引用下标为0的元素
查看数组的元素个数 ${#数组名[*]} 或${#数组名[@]}
示例
declare -a log
log=(/var/log/*.log)
for i in `seq ${#log[*]}`;do
let i++
echo log[$i]=${log[$i]}
done
~
调用数组中的元素
${NAME[@]}
${NAME[*]}
${NAME[@]:#:#}
第一个#表示跳过几个元素
第二个表示要取出的元素个数
${Name[@]:#}
表示跳过几个元素其他的全部输出
向数组中追加元素的方法:
Name[${#Name[@]}]
删除数组中的元素
unset Name[下标]
关联数组
declare -A NAME
NAME=([I_NAME]="var1" [I_NAME2]="VAR2"...)
字符串处理工具
NAME=“var"
${NAME:#:#}
偏移几个取几个字符
[root@zhangxiao ~]#N=/var/systemd/helllo
[root@zhangxiao ~]#echo ${N:3:3}
[root@zhangxiao ~]#echo “${N:3:3}”
“r/s”
${Name: -#}
取右侧字符串的几个(空格后必须有空格)
#N=/var/systemd/helllo
[root@zhangxiao ~]#echo ${N: -7}
/helllo
基于模式取子串
${VAR#*WORD}
其中word可以是指定的任意字符;
功能:自左而右,查找VAR变量中存储的字符,第一次出现的word,删除字符串开头到第一次出现word字符之间所有的字符
echo ${N#*/}
var/systemd/helllo
${VAR##*WORD}
同上不过删除的是字符串开头至最后一次匹配到wprd单词的所有字符
echo ${N##*/}
helllo
${VAR%WORD*}
同上,从右向左匹配删除到第一次匹配到WORD
${VAR%%WORD*}
同上,匹配到最后一次
查找替换:
${NAME/PATTERN/替换的内容}
自左而右查找PATTERN匹配的内容,用内容替换
${NAME//PATTERN/替换的内容}
自左而右查找PATTERN匹配的内容,用内容替换所有
${Name/^Pattern/内容}
只替换行首的Pattern内容
${Name/%Pattern/内容}
只替换行首的Pattern内容
${Name/Pattern}
自左至右查找pattern中的内容 删除
${Name//Pattern}
自左至右查找pattern中的内容 全部删除
${Name/#Pattern}
自左至右查找pattern中的内容 删除至pattern
${Name/%Pattern}
自右至左查找pattern中的内容 删除至pattern
${VAR^^}:把VAR中的小写字母换成大写
${VAR,,}:把VAR中的大写字母换成小写
变量赋值
${VAR:-VAR2}
变量有值返回VAR,没有值返回VAR2
${VAR:=VAR2}
变量有值返回VAR,没有值返回VAR2,并把VAR2赋值给VAR
${VAR:+VAR2}
如果VAR不空,返回VAR2
${VAR:?VAR2}
为空则返回VAR2(VAR2一般是错误信息)
如何为脚本提供配置文件
在脚本中. 或者sorce后边最好跟绝对路径
mktemp
mktemp /temp/Name.XXX(最好用XXX)
(X最好要出现三次)
(X会替换成随机字母或者数字)
引用临时文件
tempfile=(/temp/test.XXX)
install 命令:
用法和cp命令一致
不过选项增加
-m:指明权限
-o:指明属主
-g指明属组
可以创建空目录并指定其权限