bash脚本编程之—函数

2023年 7月 16日 67.0k 0

bash脚本编程之函数
函数:关键字
function f_name {
函数体
}
f_name() {
函数体
}
函数是做什么的,为什么要使用!!!
(1) 模块化编程;实现代码重用
(2) 代码结构更清晰,仍然是模块化编程的一个表现而已
变量类型:本地,环境,局部,特殊,位置这些变量!
一,局部变量
局部变量:函数生命周期,函数上下文
local V_NAME=VALUE
比如说:local描述,在其他全局中只要使用local,函数是不会发生变化的
#!/bin/bash
#
declare -i sum=0
sum() {
local sum=0
sum=$[$1+$2]
echo $sum
}
sum 5 6
echo $sum
了解函数递归:
函数直接或间接调用函数本身;
斐波那契数列:
1 1 2 3 5 8 13
从1开始,前两个数各是1,从第三个数开始,每一个数都是前两个数之和,这便是斐波那契数列。
阶乘:n!=n*(n-1)!=n*(n-1)*(n-2)!
#!/bin/bash
#
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact 4
数组:变量整列,通过同一个名字进行存取操作
第一个关键词:连续的多个独立的内存空间(元素),每个内存空间相当于一个变量;
数组元素:数组名[索引]
索引:从0开始编号
二:声明数组:
declare -a Array_Name
bash的属组支持稀疏格式
如何完成元素数组赋值:
方法1,一次赋值一个元素
a_name[index]-value
比如:
weekday[0]-"Sunday"
weekday[1]-"Monday"
方法2,一次赋值全部元素
weekday=(“Sunday”,"Monday","Tuserady")
[root@www ~]# weekday=("SUN" "TUE" "MED")
[root@www ~]# echo ${weekday[1]}
TUE
[root@www ~]# echo ${weekday[0]}
SUN
[root@www ~]# echo ${weekday[2]}
MED
[root@www ~]#
方法3,指定索引进行赋值
weekdays-([0]-"Sunday" [3]-"Thu" [6]-"Sat")
[root@www ~]# echo ${weekdays[0]}
Sunday
[root@www ~]# weekdays=([6]="Sat" [4]="Fri" [1]="Mon")
[root@www ~]# echo ${weekdays[1]}
Mon
[root@www ~]# echo ${weekdays[4]}
Fri
[root@www ~]# echo ${weekdays[6]}
Sat
[root@www ~]#
方法4,
-a 切割后保存在多个元素中
引用数组元素:${array_name[index]}
[root@www ~]# read -a mark
a b c
[root@www ~]# echo ${mark[1]}
b
[root@www ~]# echo ${mark[2]}
c
[root@www ~]# echo ${mark[0]}
a
[root@www ~]#
获取数组长度:${#array[*]},${#array[@]}
既数组中元素的个数;
元素个数
[root@www ~]# echo ${#mark[*]}
3
[root@www ~]#
示例一:
生成是个随机数,保存至数据中,而后显示属组索引为偶数的元素的值
[root@www ~]# echo $RANDOM:生成随机数
[root@www ~]# vim linuxEA.sh
#!/bin/bash
#
for ((i=0;i<10;i++));do
rand[$i]=$RANDOM
echo ${rand[$i]}
#随机数
done
echo "========================="
for i in `seq 0 2 9`;do
echo ${rand[$i]}
done
示例二:定义一个属组,数据元素为/var/log目录下所有以.log结尾的文件的名字;显示每个文件的行数
[root@www ~]#vim Linux.sh
#!/bin/bash
#
declare -a files
files=(/var/log/*.log)
#取长度
for i in `seq 0 $[${#files[*]}-1]`;do
#行数
wc -l ${files[$i]}
done
[root@www ~]# bash linuxea.sh
81 /var/log/anaconda.ifcfg.log
255 /var/log/anaconda.log
396 /var/log/anaconda.program.log
1341 /var/log/anaconda.storage.log
811 /var/log/anaconda.yum.log
53 /var/log/boot.log
1807 /var/log/dracut.log
59 /var/log/mysqld.log
2 /var/log/pm-powersave.log
0 /var/log/spice-vdagent.log
0 /var/log/wpa_supplicant.log
693 /var/log/Xorg.0.log
97 /var/log/yum.log
[root@www ~]#
三:数组切片
数组切片:从数组中挑选出指定的某个或某些元素
${array[@]:offset:number}
1,offset:偏移的元素的个数;
number:要取出的元素的个数
[root@www ~]# weekdays=("Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat")
取周二和周三,@偏移两个取两个
[root@www ~]# echo ${weekdays[@]:2:2}
Tue Wed
[root@www ~]#
偏移两个取剩下所有
[root@www ~]# echo ${weekdays[@]:2}
Tue Wed Thu Fri Sat
[root@www ~]#
2,${array[@]:offset:}
取出偏移量之后剩余的所有的元素
${array[@]}取所有
[root@www ~]# echo ${weekdays[@]}
Sun Mon Tue Wed Thu Fri Sat
[root@www ~]#
3,从数组中追加元素:
稀疏格式追加+1是不可以的
[root@www ~]# hello=([0]"abc" [1]="mn" [6]="hi")
[root@www ~]# echo ${#hello[*]}
3
[root@www ~]#
[root@www ~]# hello=([0]"abc" [1]="mn" [2]="hi")
[root@www ~]# hello[${#hello[*]}]="MARK"
[root@www ~]# echo ${hello[@]}
[0]abc mn hi MARK
[root@www ~]# hello[${#hello[*]}]="HOW ARE YOU"
[root@www ~]# echo ${hello[@]}
[0]abc mn hi MARK HOW ARE YOU
[root@www ~]# hello[${#hello[*]}]="is LinuxEA.com "
[root@www ~]# echo ${hello[@]}
[0]abc mn hi MARK HOW ARE YOU,is LinuxEA.com
4,从数组中删除元素:
不需要加$
unset array[index]
切除hello的第0个元素
[root@www ~]# unset hello[0]
[root@www ~]# echo ${hello[*]}
mn hi MARK HOW ARE YOU,is LinuxEA.com
[root@www ~]#
5,bash从4.0版本之后开始支持关联数组:
数组索引可为自定义的任何字符串,
定义方法:declare -A array_Name
[root@www ~]# declare -A wdays
[root@www ~]# wdays=([sun]="Sunday" [mon]="Monday" [tue]="Tuesday")
[root@www ~]# echo ${wdays[sun]}
Sunday
[root@www ~]#
四:bash的字符串处理机制:
bash的字符串处理机制:
1,
字符串切片:${var:offset:lenth}
[root@www ~]# mypath="/etc/sysconfig/network-scripts/"
取基名,先取5个
[root@www ~]# echo ${mypath:5}
sysconfig/network-scripts/
再取15个
[root@www ~]# echo ${mypath:15}
network-scripts/
15个之后再取
[root@www ~]# echo ${mypath:15:5}
netwo
[root@www ~]#
2,
取出字符的最后几个字符:${var: -length}
[root@www ~]# mypath="/etc/sysconfig/network-scripts"
取最后一个/线
[root@www ~]# echo ${mypath##*/}
network-scripts
[root@www ~]#
3,
基于模式取字串:
${var*word}:自左而右,查找var变量中存储的字符串中第一次出现的有word所指明的字符,删除此字符及其左侧的所有内容
${var##*word}:自左而右,查找var变量中存储的字符串中最后一次出现的有word所指明的字符,删除此字符及其左侧的所有内容
${var%word*} :自右而左,查找var变量中存储的字符串中第一次出现的有word所指明的字符,删除此字符及其右侧的所有内容
${var%%word*}:自右而左,查找var变量中存储的字符串中最后一次出现的有word所指明的字符,删除此字符及其右侧的所有内容
4,
如果scripts后面有/线,在自左而右找第一次/出现的位置,所有就删空了
[root@www ~]# mypath="/etc/sysconfig/network-scripts/"
[root@www ~]# echo ${mypath##*/}
[root@www ~]
如果换成C,就从/etc/sysconfig/network-s开始
[root@www ~]# echo ${mypath##*c}
ripts/
如果换成一个#号,那就是第一次出现C的时候
[root@www ~]# echo ${mypath#*c}
/sysconfig/network-scripts/
[root@www ~]#
%号是反过来的
自右而左找第一次c出现的位置,并删除字符右侧的所有内容
[root@www ~]# echo ${mypath%c*}
/etc/sysconfig/network-s
[root@www ~]#
自右而左找最后一次c出现的位置
[root@www ~]# echo ${mypath%%c*}
/et
[root@www ~]#
5,
取指定路径的目录名:
自右而左查找第一次出现/,删除/右侧的内容
[root@www ~]# mypath="/etc/sysconfig/network-scripts"
[root@www ~]# echo ${mypath%/*}
/etc/sysconfig
[root@www ~]#
示例:
[root@www ~]# url="httpd://www.linuxea.com:80"
取端口
[root@www ~]# echo ${url##*:}
80
[root@www ~]#
取协议:
[root@www ~]# echo ${url%%:*}
httpd
[root@www ~]#
五:查找替换:
查找替换:
${var/pattern/replacement}:查找var变量存储的字符中第一次由pattern匹配到的内容,并替换为replacement;
${var//pattern/replacement}:查找var变量存储的字符中所有能够由pattern匹配到的内容,并替换为replacement;
${var/#pattern/replacement}:查找var变量存储的字符中最开始处能够由pattern匹配到的内容,并替换为replacement;
${var/%pattern/replacement}:查找var变量存储的字符中最后位置能够由pattern匹配到的内容,并替换为replacement;
1,
[root@www ~]# echo ${url/com/org}
httpd://www.linuxea.org:80
[root@www ~]#
2,
替换所有替换:${var//pattern/replacement}
[root@www ~]# echo ${url//w/W}
httpd://WWW.linuxea.com:80
[root@www ~]#
3,
[root@www ~]# userinfo="root:x:0:0:root user:/root:/bin/bash/root"
[root@www ~]# echo ${userinfo/root/ROOT}
ROOT:x:0:0:root user:/root:/bin/bash
[root@www ~]# echo ${userinfo/#root/ROOT}
ROOT:x:0:0:root user:/root:/bin/bash
[root@www ~]# echo ${userinfo/%root/ROOT}
root:x:0:0:root user:/root:/bin/bash
[root@www ~]# echo ${userinfo/%root/ROOT}
root:x:0:0:root user:/root:/bin/bash/ROOT
[root@www ~]# echo ${userinfo//root/ROOT}
ROOT:x:0:0:ROOT user:/ROOT:/bin/bash/ROOT
[root@www ~]#
六:查找删除:
查找删除
${var/pattern}:查找var变量存储的字符中第一次由pattern匹配到的内容,并删除;
${var//pattern}:查找var变量存储的字符中所有能够由pattern匹配到的内容,并删除;
${var/#pattern}:查找var变量存储的字符中最开始处能够由pattern匹配到的内容,并删除;
${var/%pattern}:查找var变量存储的字符中最后位置能够由pattern匹配到的内容,并删除;
1,删除第一此出现的root
[root@www ~]# echo ${userinfo/root}
:x:0:0:root user:/root:/bin/bash/root
2,删除整个行的root
[root@www ~]# echo ${userinfo//root}
:x:0:0: user:/:/bin/bash/
[root@www ~]#
3,删除行首root
[root@www ~]# echo ${userinfo/#root}
:x:0:0:root user:/root:/bin/bash/root
4,删除行尾root
[root@www ~]# echo ${userinfo/%root}
root:x:0:0:root user:/root:/bin/bash/
[root@www ~]#
七:字符串大小写转换:
字符串大小写转换
1,
${var^^}:把var变量中的所有小写字母,统统替换为大写;
[root@www ~]# echo ${userinfo^^}
ROOT:X:0:0:ROOT USER:/ROOT:/BIN/BASH/ROOT
[root@www ~]#
2,
${var,,}:把var变量中的所有大写字母,统统替换为小写;
[root@www ~]# myinfo=${userinfo^^}
[root@www ~]# echo $myinfo
ROOT:X:0:0:ROOT USER:/ROOT:/BIN/BASH/ROOT
[root@www ~]# echo ${myinfo,,}
root:x:0:0:root user:/root:/bin/bash/root
[root@www ~]#
八:变量赋值:
变量赋值
1,${var:-word}:如果变量var为空或未声明,则返回word所表示的字符串;否则,则返回var变量的值;
2,${var:=word}:如果变量var为空或未声明,则返回word所表示的字符串,并且把word赋值为var变量;否则,则返回var变量的值;
3,${var:?error}:如果变量var为空或未声明,则返回error为错误信息;否则,则返回var变量的值;
4,${var:+word}:如果变量var为空或未声明,忽略;否则,则返回word;
[root@www ~]# echo $name
[root@www ~]# echo ${name:-tom}
tom
[root@www ~]# name=mark
[root@www ~]# echo ${name:-tom}
mark
[root@www ~]#
撤销掉name 。
1,为了避免把原有值给替换掉
[root@www ~]# unset name
[root@www ~]# name=${name:-tom}:如果name原来有值,它把自己值赋给自己,如果没有赋,则赋给name
[root@www ~]# echo $name
tom
[root@www ~]# name=${name:-jerry} :name已经有值为tom
[root@www ~]# echo $name:仍然显示tom,因为name在第一次时已经赋值
tom
[root@www ~]#
2,
[root@www ~]# unset name
[root@www ~]# echo "User's is ${name:=tom}":等于。
User's is tom
[root@www ~]# echo "User's name is ${name:=tom}"
User's name is tom
[root@www ~]# echo $name
tom
[root@www ~]#
[root@www ~]# unset name
[root@www ~]# echo "User's name is ${name:-tom}":-号是不会赋值的只会返回
User's name is tom
[root@www ~]# echo $name
[root@www ~]#
[root@www ~]# unset name
[root@www ~]# echo "User's name is ${name:?wrong}"
-bash: name: wrong
[root@www ~]# name=tom
[root@www ~]# echo "User's name is ${name:?wrong}"
User's name is tom
[root@www ~]#
如果对应的变量没有值,我们要直接引用的话,命令是不会正常运行的。
[root@www ~]# unset name
[root@www ~]# echo "User's name is ${name:?wrong}"
-bash: name: wrong
[root@www ~]# echo $?
1
[root@www ~]#
但是在有些场景下它还是有用的

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论