shell编程-循环结构
shell循环-for语句
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=0
条件 i<=多少?取决于定义。为用户输入的变量
增幅 i++ 执行一次加一
测试成产环境的主机存活性,将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\n" >> ip_up.txt
else
echo "down: $src_ip.$i\n" >> ip_down.txt
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
#!/bin/bash
while :
do
read -p "请设置用户名/数量/密码: " prefix num pass
cat <<-EOF
用户前缀:$prefix
用户数量:$num
用户密码:$pass
EOF
read -p "是否确认创建:[Y/N]" action
if [ $action = y ];then
break #跳出循环
fi
done
echo "starting create users..."
for i in `seq -w $num`
do
user=$prefix$i
id $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is already exist"
else
useradd $user
echo $pass | passwd --stdin $user &>/dev/null
fi
done
[root@linux-server script]# chmod +x user.sh
[root@linux-server script]# ./user.sh
参数详解:
seq 打印序列号,只跟数字
打印奇数: seq 1 2 10:表示1到10以内的奇数,2是步长,因为中间隔2.
seq -w $num :-w 所有数取最宽的宽度,前面没有的自动补零。
shell 循环while语句
while 条件
do
循环体
done
完善系统工具的输出及操作性
创建一个用户并记录到文件中:
[root@linux-server script]# vim adduser.sh
#!/bin/bash
while read user
do
id $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is already exists"
else
useradd $user
echo "create $user successfully" && echo "$user" >> user.txt
fi
done
[root@linux-server script]# chmod +x adduser.sh
[root@linux-server script]# ./adduser.sh
#注意观察添加exit与不添加有什么区别
案例二:
[root@linux-server script]# vim while.sh
#!/usr/bin/env bash
#
# Author:
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 "请按照上方提供的选项输入!!!"
;;
esac
if [ $? -eq 0 ];then
clear
else
echo "Warning: Your program exist ERROR!!!"
break
fi
done
[root@linux-server script]# chmod +x while.sh
[root@linux-server script]# ./while.sh
练习题:
输入用户输入的参数,直到用户输入 "end" 结束循环
shell循环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
参数解释:
expr命令可以实现数值运算、数值或字符串比较、字符串匹配、字符串提取、字符串长度计算等功能
shell 循环控制shift、continue、break、exit
shift命令
位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢 弃,$0不移动。不带参数的shift命令相当于shift 1。
对于位置变量或命令行参数,其个数必须是确定的,或者当 Shell 程序不知道其个数时,可以把所有参数一起赋值给变量 $*。
若用户要求 Shell 在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在 $1 后为 $2,在 $2 后面为 $3 等,则需要用shift把所有参数变成$1
#测试 shift 命令(x_shift3.sh)
[root@linux-server script]# cat x_shift3.sh
#!/bin/bash
shift
echo "第一个位置参数: $1"
[root@linux-server script]# bash x_shift3.sh 2 3
第一个位置参数: 3
#测试 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 命令每执行一次,变量的个数($#)减一,而变量值提前一位
练习:
用 until 和 shift 命令计算所有命令行参数的和。
[root@linux-server script]# vim x_shift2.sh
sum=0
until [ $# -eq 0 ]
do
sum=`expr $sum + $1`
shift
done
echo "sum is: $sum"
执行上述程序:
[root@linux-server script]# bash x_shift2.sh 3 5 7
其显示结果为:
15
continue、break、exit命令
Linux脚本中的break continue exit return
break
结束并退出本次循环
continue
在循环中不执行continue下面的代码,转而进入下一轮循环
exit
退出脚本
常带一个整数给系统,如 exit 0
可理解为:break是立马跳出循环;continue是跳出当前条件循环,继续下一轮条件循环;exit是直接退出整个脚本
例如:
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,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
[root@linux-server script]# bash break.sh
#将break注释掉观察结果
continue命令
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
对上面的例子进行修改:
代码如下:
[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的数字时,该例中的循环不会结束.
break和exit的区别
[root@linux-server script]# vim case07.sh
#!/bin/bash
while true
do
read -p "请输入[1/2]" num1
case $num1 in
1)
echo $num1
;;
2)
while true
do
read -p "再次输入[1/2]:" num2
case $num2 in
1)
echo $num2
;;
2)
break;; #将此处换成exit,再次尝试
#exit;;
esac
done
esac
done
实战-shell版本jumpserver开发(堡垒机) ----待定
ps:整理自己的思路,完善不足的地方
#!/usr/bin/env bash
#
# Author:
#可以先添加上账密验证环节
while :
do
trap ':' INT EXIT TSTP TERM HUP
clear
cat <<-EOF
+-------------------------------------+
| JumpServer @Version1.0 |
+-------------------------------------+
| a. WebServer Apache. |
| b. MySQL Databases Server. |
| c. PHP Development Computer. |
| d. Quit |
+-------------------------------------+
EOF
read -p "Please input your jump to server's number: " computer
case $computer in
a)
ssh jumper@192.168.161.129 //可以嵌套子case循环
;;
b)
ssh jumper@192.168.161.130
;;
c)
ssh jumper@192.168.161.131
;;
d)
exit
;;
*)
printf "ERROR: Please redo your select!"
;;
esac
done