shell编程-条件结构
测试-----test 条件
#条件为真返回 0,条件为假返回 1 #语法------[ 条件 ]
test 能够理解3中类型的表达式
1.文件测试
2.字符串比较
3.数字比较
字符串
-n STRING -n 字符串的长度不是零,成功。
-z STRING -z 字符串长度是零,成功 #对于未定义或赋予空值的变量将是为空串。
STRING1 = STRING2 (等于)
STRING1 != STRING2 (不等于)
# vim string.sh
#!/usr/bin/bash
read -p "请输入你的密码: " a
pass=123456
if [ -z $a ];then
echo "您输入的密码不能为空"
exit 1
else
if [ $a = $pass ];then
echo "登录成功"
break
else
echo "您的密码输入有误,请重新输入"
fi
fi
#数字
-eq(equal) 等于
-ne(not equal) 不等于
-ge(Greater than or equal to) 大于等于
-le(Less than or equal to) 小于等于
-gt(greater than) 大于
-lt(less than) 小于
#文件————判断测试
-f 存在且是普通文件
-d 存在且是目录
-h 存在且是符号链接
-b 块设备
-c 字符设备
-e 文件或者目录存在
shell分支if语句
流控制:
•在一个shell脚本中的命令执行顺序称作脚本的流。大多数脚本会根据一个或多个条件来改变它们的流。
•流控制命令:能让脚本的流根据条件而改变的命令称为条件流控制命令
•exit语句:退出程序的执行,并返回一个返回码,返回码为0正常退出,非0为非正常退出,例如:
•exit 0
条件判断语法:
if [ 判断条件 ]---代码返回0表示真,非0为假.在[ 和 ] 以及操作符和操作数之间添加空格是必需的
if语句语法如下:
if [ list1 ];then list1:你的测试条件,你要测试什么,对什么内容做判断
list2
elif [ list3 ];then ---------------> 接着在怎么做。(多条件判断)
list4
else ---------------> 如果前面的命令没有执行成功那就执行else下面的命令。
list5
fi
多个条件联合
&&:逻辑与,前面执行成功,后面才执行。前面命令执行失败,后面命令也不执行
if [ $condition1 ] && [ $condition2 ];then
if [[ $condition1 && $condition2 ]];then
||:逻辑或,前面执行失败,后面执行,前面命令执行成功,后面不执行。
if [ $condition1 ] || [ $condition2 ];then
if [[ $condition1 || $condition2 ]];then
例:
[root@linux-server ~]# cd /opt/test/script/
[root@linux-server script]# vim testif.sh
#!/bin/bash
read -p "请输入号码: " num
if [ $num = 1 ];then
echo "1"
elif [ $num = 2 ];then
echo "2"
else
echo "输入有误!"
fi
[root@linux-server script]# chmod +x testif.sh
例:脚本if.sh,必须在脚本后加上适当的参数脚本才能正确执行
[root@linux-server script]# vim if.sh
#!/bin/bash
if [ "$1" = "hello" ]; then
echo "Hello! How are you ?"
elif [ "$1" = "" ]; then
echo "You MUST input parameters"
else
echo "The only accept parclear ameter is hello"
fi
[root@linux-server script]# chmod +x if.sh
测试:
[root@linux-server script]# ./if.sh
[root@linux-server script]# ./if.sh hello
[root@linux-server script]# ./if.sh 434
练习
1.测试ip地址主机位从2到100的机器是否存活,并把存活的机器记录到文本文件alivehost.txt内。(使用ping命令)
案例
#!/usr/bin/bash
ip=192.168.198
for i in {2..100}
do
ping -c1 $ip.$i &> /dev/null
if [ $? -eq 0 ];then
echo "$ip.$i is up" >> activehost.txt
else
echo "$ip.$i is down"
fi
done
作业
1. 判断一个用户是否存在
2. 判断当前内核主版本是否为3,且次版本是否大于10
#!/bin/bash
kernel_version=$(uname -r)
m_ver=`uname -r | awk -F'.' '{print $1}'`
s_ver=$(uname -r | awk -F'.' '{print $2}')
if [[ $m_ver == 3 && s_ver -ge 10 ]]; then
echo "主版本为3且此版本大于等于10"
else
echo "不符合"
fi
2. 判断vsftpd软件包是否安装,如果没有则自动安装 (yum是否能用,
不能用自动修复配置yum源,安装完vsftpd后测试是否能用).
#!/bin/bash
#检查vsftpd软件包是否已安装
if ! rpm -q vsftpd >/dev/null; then
echo "vsftpd软件包未安装"
#检查yum是否可用
if ! which yum >/dev/null; then
echo "yum命令不可用,正在修复yum源……"
#修复yum源
yum -y install expel-release
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache
#再次检查yum命令是否可用
if ! rpm -q yum >/dev/null; then
echo "修复失败,请手动修复yum源后重新运行脚本"
exit 1
fi
fi
#使用yum安装vsftpd软件包
yum -y install vsftpd
#检查安装结果
if [ $? -eq 0 ]; then
echo "vsftpd安装成功"
echo "正在监测vsftpd是否可用..."
#测试vsftpd
systemctl start vsftpd
systemctl status vsftpd
if [ $? -eq 0 ]; then
echo "vsftpd服务正常运行"
exit 0
else
echo "vsftpd服务未能正常启动,请检查配置"
exit 1
fi
else
echo "vsftpd软件包安装失败"
exit 1
fi
else
echo "vsftpd软件包已安装 "
fi
4. 判断指定的主机是否能ping通,必须使用$1变量
#!/bin/bash
read -p "输入要Ping的地址:" host # 定义要ping的主机
ping_result=$(ping -c 4 $host) # 尝试ping主机,-c 4 表示发送4个ICMP请求包
if [ $? -eq 0 ]; then # 检查ping命令的退出状态
echo "主机 $host 可达。"
# 使用grep和awk来解析ping输出中的统计信息
packets_sent=$(echo "$ping_result" | grep "transmitted" | awk '{print $1}')
packets_received=$(echo "$ping_result" | grep "received" | awk '{print $1}')
packet_loss=$(echo "$ping_result" | grep "packet loss" | awk '{print $1}')
rtt_min=$(echo "$ping_result" | grep "rtt min/avg/max/mdev" | awk '{print $3}')
rtt_avg=$(echo "$ping_result" | grep "rtt min/avg/max/mdev" | awk '{print $4}')
rtt_max=$(echo "$ping_result" | grep "rtt min/avg/max/mdev" | awk '{print $5}')
echo "发送的数据包: $packets_sent"
echo "接收的数据包: $packets_received"
echo "数据包丢失率: $packet_loss%"
echo "RTT 最小值: $rtt_min ms"
echo "RTT 平均值: $rtt_avg ms"
echo "RTT 最大值: $rtt_max ms"
else
echo "主机 $host 不可达。"
fi
shell 分支case语句
case 语句是 shell 流控制的第二种方式,语法如下:
case $变量 in
pattern1)
list1
;; ---------------结尾。
pattern2)
list2
;;
... ...
patternN)
listN
;;
*) -------------> 如果前面命令没有执行成功那么执行下面这个
list*
;;
esac
命令;;表明流应该跳转到case语句的最后,类似C语言中的break指令。
第一行: 声明case关键字调用case语法, 紧跟的“变量”一般为用户的输入值, in代表从下方的各个模式进行匹配
第2-4行: 匹配到“pattern1”后进行命令的输出或执行, pattern1: 一般为字符或数值
第11-12行: 当用户输入的字符不存在匹配模式时, 直接执行或打印*)下的命令或语句
实例1
判断用户输入的是否是数字
#!/bin/bash
read -p "请输入:" input
case $input in
''|*[!0-9]*) #如果输入为空或包含非数字字符
echo "输入的不是纯数字"
;;
*) #如果输入只包含数字
echo -e "输入的是纯数字\n"
;;
esac
实例2:
建立脚本case.sh,当执行时,要求我们在键盘输入适当的值(one|two|three),当输入正确时并打印,当输入错误 时会提示你,应该输入正确的值。
#!/usr/bin/env bash
while true; do
read -p "请输入one、two或three:" input
case $input in
one)
echo "输入了one"
break
;;
two)
echo "输入了two"
break
;;
three)
echo "输入了three"
break
;;
*)
echo "输入错误,请重新输入"
;;
esac
done
示例2:
[root@linux-server script]# vim system_tools.sh
#!/usr/bin/env bash
cat <<-EOF
+-------------------------------------------------------------------------+
| System_tools V1.0 |
+-------------------------------------------------------------------------+
| a. Stop And Disabled Firewalld. |
| b. Disabled SELinux Secure System. |
| c. Install Apache Service. |
| d. Quit |
+-------------------------------------------------------------------------+
EOF
echo "Please input your select: " && read var
case "$var" in
"a")
systemctl stop firewalld && systemctl disable firewalld
;;
"b")
setenforce 0
;;
"c")
yum -y install httpd httpd-tools
;;
"d")
exit
;;
*)
echo "请按照上方提供的选项输入!!!"
;;
esac
[root@linux-server script]# chmod +x system_tools.sh
[root@linux-server script]# ./system_tools.sh
练习:
1.建立脚本service.sh,当执行的时候要求输入(1、2、3、4、5)时安装对应的httpd、vim、wget、更换aliyum等功能,当输入错误 时会提示你,应该输入正确的值。
shell编程-循环结构
for语句
for i in {取值范围} #for是关键字 i是变量名 in是关键字
do #循环体的开始
循环体
done #循环体的结束
实战1:
[root@linux-server script]# vim for.sh
#!/usr/bin/env bash
#
# Author:
# Date: 2019/**/**
for i in {1..100}
do
echo $i
done
[root@linux-server script]# vim for1.sh
#!/bin/bash
for (( i=1;i <= 5;i++ ))
do
echo "$i"
done
[root@linux-server script]# chmod +x for1.sh
[root@linux-server script]# ./for1.sh
参数解释:
默认值 i=1
条件 i<=多少?取决于定义,为用户输入的变量,先条件成立在执行命令
增幅 i++ 执行一次加一
区别:
i++===先赋值在运算
++i===先运算在赋值
例子
[root@localhost script]# i=1
[root@localhost script]# h=1
[root@localhost script]# let x=i++
[root@localhost script]# echo $x
1
[root@localhost script]# echo $i
2
[root@localhost script]# let y=++h
[root@localhost script]# echo $y
2
[root@localhost script]# echo $h
2
测试生产环境的主机存活性,将up的ip保存在一个文件中,将down的ip保存在一个文件中
[root@linux-server script]# vim ip.sh
#!/usr/bin/env bash
# Author:
src_ip="192.168.246"
for i in {2..254}
do
{
ping -c1 $src_ip.$i &>/dev/null
if [ $? -eq 0 ];then
echo "alive: $src_ip.$i" >> ip_up.txt
echo "alive: $src_ip.$i"
else
echo "down: $src_ip.$i" >> ip_down.txt
echo "down: $src_ip.$i"
fi
} &
done
wait
echo "finish..."
[root@linux-server script]# chmod +x ip.sh
[root@linux-server script]# ./ip.sh
参数详解:
wait:等待上面命令后台执行结束后(即上一个的进程终止),在执行下面的echo命令
{}加上就可以看成一个整体的进程
for循环批量创建用户
[root@linux-server script]# vim user.sh
#!/usr/bin/bash
read -p "请设置用户名/数量/密码: " prefix num pass
cat <<-EOF
用户前缀:$prefix
用户数量:$num
用户密码:$pass
EOF
for i in $(seq 1 $num)
do
user=$prefix$i
id $user &> /dev/null
if [ $? -eq 0 ];then
echo "$user is already exist!"
exit 0
else
useradd $user &> /dev/null
echo $pass | passwd --stdin $user &>/dev/null
fi
done
echo "starting create users..."
[root@linux-server script]# chmod +x user.sh
[root@linux-server script]# ./user.sh
参数详解:
seq 打印序列号,命令用于产生从某个数到另外一个数之间的所有整数。
为什么不能在{ }中使用变量。
Bash中会最先展开{ }中的内容,这个时候$NUM还不会被具体的值替代,所以是i在循环中读取的是‘{1..$NUM}’的一个完整的字符串,输出时$NUM会被10替代,就有了'{1..10}'这样的结果。
seq序列
seq [OPTION]... FIRST INCREMENT LAST
seq 1 -1 10 生成从10到1的递减序列
seq 1 2 10 生成从1到10,步长为2的序列
seq a z 生成从a到z的字母序列:
while语句
while 条件
do
循环体
done
注意:while循环处理文件里面的行比较擅长,不管有没有空格都是一行。
while关键字,条件和if的条件一样,#while循环当条件为真的时候进入循环,同时会一直循环,也就所说的死循环,为假时不循环
完善系统工具的输出及操作性
#通过一个文件批量创建用户:
#背景:写一个脚本,满足以下需求及应用,如一个文件的内容如下,根据文件内容实现批量创建用户,第一列为用户名,第二列为密码
[root@localhost script]# vim user_pass.txt #创建用户和密码文件
user1 qfedu123
user2 qfedu456
user3 qfedu567
user4 qfedu789
user5 qfedu012
[root@localhost script]# vim create_user.sh #编写脚本
#!/usr/bin/bash
[ $UID -ne 0 ] && exit 1
while read line
do
user=`echo $line | awk '{print $1}'`
pass=`echo $line | awk '{print $2}'`
id $user &> /dev/null || useradd $user && echo $pass | passwd $user --stdin
done < /opt/test/script/user_pass.txt
[root@localhost script]# chmod +x create_user.sh
[root@localhost script]# bash create_user.sh
案例二:
[root@linux-server script]# vim while.sh
#!/usr/bin/bash
while 1>0
do
cat <<-EOF
+-------------------------------------------------------------------------+
| System_tools V1.0 |
+-------------------------------------------------------------------------+
| a. Stop And Disabled Firewalld. |
| b. Disabled SELinux Secure System. |
| c. Install Apache Service. |
| d. Quit |
+-------------------------------------------------------------------------+
EOF
echo " Please input your select: " && read var
case "$var" in
"a")
systemctl stop firewalld && systemctl disable firewalld
;;
"b")
sed -ri s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
;;
"c")
yum -y install httpd httpd-tools
;;
"d")
exit
;;
*)
echo "请按照上方提供的选项输入!!!"
sleep 2
clear
;;
esac
done
[root@linux-server script]# chmod +x while.sh
[root@linux-server script]# ./while.sh
案例三嵌套循环
[root@localhost script]# vim test4.sh
#!/usr/bin/bash
for i in {1..100}
do
while [ $i -lt 50 ]
do
echo $i
#let i++
done
done
[root@localhost script]# chmod +x test4.sh
[root@localhost script]# bash test4.sh
练习题:
1.输入用户输入的参数,直到用户输入 "end" 结束循环
2.给脚本service.sh进行修改,当执行的时候要求输入(1、2、3、4、5)时安装对应的httpd、vim、wget、更换aliyum等功能,当输入错误 时提示应该输入正确的值但是不会退出。
3.建立批量删除用户脚本
# vim deluser.sh
#!/usr/bin/bash
read -p "请输入用户名: " na
read -p "请输入要删除的个数? " num
echo $num
read -p "确认要删除$na[Y|y]: " x
if [ $x = Y ] || [ $x = y ];then
for i in $(seq 1 $num )
do
echo "$i"
user=$na"$i"
id $user
if [ $? -eq 0 ];then
userdel -r $user
else
exit 9
fi
done
fi
#chmod +x deluser.sh
#./deluser.sh
until语句
until 条件 #当后面的条件表达式为假的时候的才循环,为真的时候就停止了
do
循环体
done
[root@linux-server script]# cat until.sh
#!/bin/bash
x=1
until [ $x -ge 10 ]
do
echo $x
x=`expr $x + 1`
done
x=1
while [ ! $x -ge 10 ]
do
echo $x
x=`expr $x + 1`
done
[root@linux-server script]# chmod +x until.sh
[root@linux-server script]# ./until.sh
循环控制
shift
shift命令
将命令行参数列表中的位置参数向左移动,并更新变量$1、$2等的值。
比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢弃,$0不移动。
不带参数的shift命令相当于shift 1。
语法:shift [n]
#测试 shift 命令
[root@linux-server script]# cat x_shift3.sh
#!/bin/bash
shift
echo "第一个位置参数: $1"
[root@linux-server script]# bash x_shift3.sh 2 3
第一个位置参数: 3
若用户要求 Shell 在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在 $1 后为 $2,在 $2 后面为 $3 等,则需要用shift把所有参数变成$1
#测试 shift 命令(x_shift.sh)
[root@linux-server script]# vim x_shift.sh
#!/bin/bash
until [ $# -eq 0 ]
do
echo "第一个参数为: $1 参数个数为: $#"
shift
done
执行以上程序:
[root@linux-server script]# bash x_shift3.sh 1 2 3 4
结果显示如下:
第一个参数为: 1 参数个数为: 4
第一个参数为: 2 参数个数为: 3
第一个参数为: 3 参数个数为: 2
第一个参数为: 4 参数个数为: 1
从上可知 shift 命令每执行一次,变量的个数($#)减一,而变量值提前一位
continue、break、exit
#continue、break、exit命令
Linux脚本中的break continue exit
1.break
结束并退出本次循环
2.continue
在循环中不执行continue下面的代码(跳出当前条件循环),继续下一轮条件循环
3.exit
直接退出整个脚本,一般返回一个状态码给系统
默认情况下,退出状态码为0,表示正常退出。
非零的退出状态码通常用于指示错误或异常情况,具体含义需要自定义
状态码:
0:表示正常退出。当脚本执行成功且没有发生错误时,可以使用状态码0。
1:通常表示一般性的错误。例如,输入参数有误或未满足某些条件时可以返回1。
2:表示无效或不支持的命令行选项。
127:表示命令未找到,即某个被调用的命令不存在。
128+:表示脚本因收到信号而终止。例如,状态码130表示脚本收到了Ctrl+C的中断信号。
255:表示退出状态码超过了范围(0-255)。
【实例】
[root@localhost script]# vim break.sh
#!/usr/bin/bash
for i in {1..10}
do
if [ $i -eq 7 ];then
continue
#break
#exit 34
else
echo $i
fi
echo "本次输出结束"
done
echo "脚本结束循环"
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
break命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
以下脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。
代码如下:
[root@linux-server script]# vim break.sh
#!/bin/bash
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5)
echo "Your number is $aNum!"
;;
*)
echo "You do not select a number between 1 to 5, game is over!"
break
;;
esac
done
#将break注释掉观察结果
案例2:continue
continue命令
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
[root@linux-server script]# bash break.sh
对上面的例子进行修改:
代码如下:
[root@linux-server script]# vim break1.sh
#!/bin/bash
while : #默认为真
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5)
echo "Your number is $aNum!"
;;
*)
echo "You do not select a number between 1 to 5, game is over!"
continue
;;
esac
done
[root@linux-server script]# bash break1.sh
#运行代码发现,当输入大于5的数字时,该例中的循环不会结束.
shell 编程-函数
function (功能) 功能函数 完成特定功能的代码片段 函数必须先定义才能使用 优点:避免重复的代码 定义函数---怎么写函数脚本,如何定义 调用函数--- 怎么使用函数,本地调用,2。通过其他脚本调用 取消函数---- unset func_name 函数传参----和脚本传参类似 命名空间:在shell语言中函数的命名空间是函数内和函数外,定义变量是一样的,函数内外不能赋值同样名字的变量 #变量:如果在同一个命名空间可以用,如果不再同一个命名空间就不能用 #函数变量使用的范围:默认,函数里的变量会在函数外面生效 #函数变量如果不让在其他空间用使用:local 分开 local 变量名称 #变量只在函数内生效。属于局部变量 # vim var.sh #!/usr/bin/bash a=10 var() { echo $a #local a a=20 echo $a } var #调用函数 echo $a #return: 返回结果并退出函数 返回值:return value:#value不能超过0-255,是函数里面函数最后一条执行命令的返回值,默认返回值是由这条命令执行结果确定的. [root@localhost ~]# vim return.sh #!/usr/bin/bash func(){ echo "hello" return 250 #函数返回值 } func #echo $? #返回的是函数的返回值 if [ $? -eq 250 ];then echo "成功" else echo "失败" fi exit:返回结果并退出程序
函数function
函数声明
function_name () {
list of commands
}
函数名 function_name,这就是你将使用它从其他地方在你的脚本调用。
取消函数
unset function_name #取消函数
[root@linux-server script]# vim func.sh
#!/bin/bash
myfunc(){ #定义函数
echo “This is my first shell function”
}
myfunc #函数调用
产生以下执行结果
[root@linux-server script]# bash func.sh
“This is my first shell function”
函数必须提前定义测试
[root@linux-server script]# vim fun01.sh
#!/bin/bash
fun() {
echo "hello"
}
fun
unset fun #取消函数
fun
[root@linux-server script]# bash fun01.sh
hello
fun01.sh: line 7: fun: command not found
函数调用
定义函数脚本
[root@localhost script]# cat a.sh
#!/usr/bin/bash
check_net() {
echo "正在检查网络通信"
ping -c1 www.baidu.com 2&> /dev/null
if [ $? -eq 0 ];then
echo "你的网络是没有问题的"
else
echo "你的网络有问题,请先检查网络"
exit 2
fi
}
check_net #本地调用
echo "+++++++++++++++++++++++++++++++++++++++++++++"
check_yum() {
echo "正在检查yum源是否可用"
yum repolist
if [ $? -eq 0 ];then
echo "你的yum源可以正常使用"
else
echo "yum源不能用,请手动配置网络yum源"
exit 3
fi
}
#check_yum
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++"
install_nginx() {
#检查网络是否可以上网
check_net
echo "正在配置nginx的yum源"
cat > /etc/yum.repos.d/nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/7/x86_64/
gpgcheck=0
enabled=1
EOF
yum clean all && sleep 2
yum install -y nginx 2&> /dev/null
if [ $? -eq 0 ];then
echo "nginx install successfull and start nginx"
sleep 2
systemctl start nginx
if [ $? -eq 0 ];then
echo "nginx started is success,please check port!"
port=`netstat -lntp | grep nginx | awk '{print $4}' | awk -F ":" '{print $NF}'`
echo "nginx is port $port"
else
echo "nginx 启动失败,请手动检查!"
exit 4
fi
else
echo "nginx install failed!将会自动退出"
exit 5
fi
}
#install_nginx
函数调用
root@localhost script]# cat b.sh #通过其他脚本调用函数脚本
#!/usr/bin/bash
while :
do
echo "这是服务器基本检测功能脚本"
cat <<EOF
++++++++++++++++++++++++++++++++++
+ 1. 检查yum源 +
+ 2. 检查网络 +
+ 3. 安装nginx +
+ 4. 退出 +
++++++++++++++++++++++++++++++++++
EOF
source ./a.sh #写你函数脚本的绝对路径,这里指的是执行函数脚本,让它为下面调用函数生效
read -p "请输入你的选项: " num
case $num in
1)
check_yum
;;
2)
check_net
;;
3)
install_nginx
;;
4)
exit;;
*)
echo "你输入的选项失败请重新输入"
esac
done
函数传参
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 位置参数来进行传参的,$1表示第一个参数,$2表示第二个参数...
示例
[root@linux-server script]# vim fun04.sh
fun() {
echo $[$1*$2*$3]
}
fun $1 $2 $3
[root@linux-server script]# bash fun04.sh 1 3 5
15
local变量
local
是 Bash shell 中的一个关键字,用于声明局部变量。在 Bash 脚本中,local
主要用于函数内部,以声明仅在该函数作用域内可见的变量。这有助于减少全局变量的数量,提高脚本的可维护性和避免潜在的命名冲突。
声明普通变量:
local variable_name=value
声明数组变量:
local -a array_name=(element1 element2 element3 ...)
关联数组(键值对):
local -A assoc_array_name=( [key1]=value1 [key2]=value2 [key3]=value3 ... )
声明变量并赋默认值:
local variable_name=${variable_name:-default_value}
shell 编程-数组
什么是数组? 数组也是一种变量,常规变量只能保存一个值,数组可以保存多个值 #普通数组:只能用整数作为数组的索引--0 下标 #关联数组:可以使用字符串作为数组的索引
数组定义
普通数组定义
# books=( linux shell awk sed ) ---在python中叫列表
引用: echo ${array_name[index]}
# echo ${books[0]}
linux
# echo ${books[1]}
shell
# echo ${books[2]}
awk
#关联数组需要提前声明
Declare命令:
# declare [-选项]
参数说明:
-a :#定义为数组--array
-A : #定义关联数组
例1
declare -A myarry1
# declare -A myarry1
# myarry1=([name]=soso666 [sex]=man [age]=18)
# echo ${myarry1[name]}
soso666
[root@linux-server script]# echo ${myarry1[age]}
18
数组定义方法:
定义方法1:
# array=( one two three four five six )
# array1=(`cat /etc/passwd`) #希望是将文件中的每一行作为一个值赋给数组array3
# array2=(1 2 3 4 5 6 7 "linux shell" [20]=saltstack)
定义方法2:指定索引赋值
语法:数组名[index]=变量值
示例
[root@linux-server script]# vim shuzu.sh
#!/bin/bash
NAME[0]="BJ"
NAME[1]="SH"
NAME[2]="SZ"
NAME[3]="GZ"
NAME[4]="HZ"
NAME[5]="ZZ"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"
echo "sixth Index: ${NAME[5]}"
输出结果
[root@linux-server script]# bash shuzu.sh
First Index: BJ
Second Index: SH
sixth Index: ZZ
访问数组
当设置任何数组变量时,可以访问它
# aa=(haha heihei baibai)
# echo ${aa[0]} #访问数组中的第一个元素
# echo ${aa[@]} #访问数组中所有的元素 等同与echo ${aa[*]}
# echo ${#aa[@]} #统计元素的个数
# echo ${!aa[@]} #打印数组的所有索引
您可以访问数组中的所有项目通过以下方式之一:
${array_name[*]}
${array_name[@]}
疑难点 shell数组中"*" 和 "@" 区别
关于在shell脚本中数组变量中 “*”跟 “@” 区别
1.*当变量加上"" 会当成一串字符串处理.
2.@当变量加上"" 依然当做数组处理,在没有加上"" 的情况下效果是一样的数组
[root@linux-server script]# vim test1.sh
#!/usr/bin/env bash
array=(gz cloud 19)
echo "case 1"
for line in "${array[@]}"
do
echo $line
done
echo "case 2"
for line in "${array[*]}"
do
echo $line
done
echo "case 3"
for line in ${array[*]}
do
echo $line
done
echo "case 4"
for line in ${array[@]}
do
echo $line
done
执行结果
[root@linux-server script]# bash test1.sh
case 1 使用 ${array[@]} 来迭代数组,每个元素都被正确地输出到新的一行。
gz
cloud
19
case 2 使用 ${array[*]} 迭代数组,所有元素作为一个字符串输出,元素之间没有空格分隔。
gz cloud 19
case 3 没有使用双引号 (") 来包围 ${array[*]}。正确地输出了每个元素到新的一行
gz
cloud
19
case 4 使用 ${array[@]} 来迭代数组,每个元素也被正确地输出到新的一行。
gz
cloud
19
可以看的case2这是因为默认的内部字段分隔符 IFS (Internal Field Separator) 在这种情况下不起作用。
[root@mysql-server script]# vim shuzu.sh
#!/bin/bash
src_ip=(192.168.0.123 192.168.0.124 192.168.0.125 192.168.0.126 192.168.0.127)
#echo ${src_ip[@]}
ip_name=(web-1 web-2 java-1 java-2 mysql-server)
#echo ${ip_name[*]}
for (( i=0; i<${#src_ip[@]}; i++ ))
do
echo $i-----${src_ip[i]}-----${ip_name[i]}
done
练习
#!/bin/bash
1.检査机器是否可以上网
2.检查yum是否可用
3.安装一些必要工具(vim/wget/net-tools/ntpdate)
4.检查nginx是否安装,
5.替换yum源--nginx
6.安装nginx----yum install-y nginx启动