Shell循环:for
循环次数是固定的
=====================
Shell:
for 变量名 [in 取值列表]
do
循环体
done
C语言:
for((初值;条件;步长))
do
循环体
done
=====================
Shell循环:while until
循环次数不一定是固定的
可以固定
可以不固定
while语句:
while 条件测试
do
循环体
done
功能:当条件测试成立(条件测试为真),执行循环体。
=====================
until语句:
until 条件测试
do
循环体
done
功能:当条件测试成立(条件测试为假),执行循环体。
=====================
案例1:循环输出变量i的值。下例可直接在命令行测试。
for i in a b c d
do
echo $i
done
=====================
案例2:批量ping测试主机,并发方式。
vi pi.sh 脚本代码如下
#!/usr/bin/env bash
trap "echo ok;exit 3" INT
for i in {1..254}
do
(
ip=192.168.100.$i
ping -w.2 -i.1 -c1 $ip | grep -q 'ttl'
[ $? -eq 0 ] && echo "$ip is up" || echo "$ip is down"
) &
done
wait
echo "finish...."
测试效率:time sh pi.sh
=====================
案例1:写脚本s1.sh。提示用户输入功能选项,回车后执行相关的命令。
vi s1.sh 脚本代码如下
#!/bin/bash
#trap "echo ok;exit;" HUP INT QUIT TSTP
while :
do
cat <<-EOF
1.web1
2.web2
3.MysqL1
EOF
read -p "input number[1-3]:" num
case $num in
1)
#ssh root@192.168.10.25
ping -c 4 127.0.0.1
;;
2)
#ssh root@192.168.10.26
ping -c 4 127.0.0.2
;;
3)
#ssh root@192.168.10.27
ping -c 4 127.0.0.3
;;
'')
true
;;
*)
echo "error"
break
;;
esac
done
----------------------------------------
案例3:多主机推送公钥。
vi skey.sh
#!/usr/bin/env bash
#get ip
>/tmp/ip_yes.txt
>/tmp/ip_no.txt
if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
fi
rpm -q expect &> /dev/null
if [ $? -ne 0 ];then
yum install -y expect
fi
for i in {1..254}
do
{
ip=192.168.100.$i
ping -W.2 -i.1 -c1 $ip &> /dev/null
if [ $? -eq 0 ];then
echo "$ip is up" | tee -a /tmp/ip_yes.txt
/usr/bin/expect <<-EOF
set timeout 10
spawn ssh-copy-id $ip
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "012\r" }
}
expect eof
EOF
else
echo "$ip is down" | tee -a /tmp/ip_no.txt
fi
}&
done
wait
echo "finish...."
=====================
案例4:{}&并发的批量修改ssh服务器上的sshd_config配置文件、selinux配置文件,关闭防火墙。
第1步:准备/opt/ip.txt文件。
cat > /opt/ip.txt <<EOF
192.168.10.2
192.168.10.25
192.168.10.26
EOF
第2步:创建脚本。
vi ssh.sh
#!/usr/bin/env bash
for ip in $(cat /opt/ip.txt)
do
{
ssh $ip "sed -ri '/^#UseDNS/c\UseDNS no' /etc/ssh/sshd_config"
ssh $ip "sed -ri '/^GSSAPIAuthentication yes/c\GSSAPIAuthentication no' /etc/ssh/sshd_config"
ssh $ip "service iptables stop;chkconfig iptables off"
ssh $ip "sed -ri '/^SELINUX/c\SELINUX=permissive' /etc/selinux/config"
ssh $ip "setenforce 0"
}&
done
wait
echo "finish..."
=====================
案例4:多主机修改密码。
vi modify_passwd.sh
#!/usr/bin/env bash
#change password
#v1.0 by flyer 08/10/2017
read -p "Please input a New Password:" pass
for i in {1..100}
do
{
ip=192.168.100.$i
ping -c1 -W1 $ip &>/dev/null
if [ $? -eq 0 ];then
ssh $ip "echo $pass | passwd --stdin root" &> /dev/null
if [ $? -eq 0 ];then
echo "$(date +%F) $ip up" >> /tmp/ok.txt
else
echo "$(date +%F) $ip down" >> /tmp/fail.txt
fi
else
echo "$(date +%F) $ip down" >> /tmp/fail.txt
fi
}&
done
wait
echo "all ok...."
=====================
案例:for批量创建用户。
cat > /tmp/user.txt <<EOF
tom
jack
lucy
EOF
第2步:创建脚本文件。
vi useradd.sh
#!/usr/bin/env bash
#useradd2
pass=111
red_col="\e[1;31m"
reset_col="\e[0m"
if [ $# -eq 0 ];then
echo "Usage: $(basename $0) file"
exit 1
fi
if [ ! -f $1 ];then
echo "Error File!"
exit 2
fi
for user in $(cat $1)
do
id $user &> /dev/null
if [ $? -eq 0 ];then
echo "$user already exites"
else
useradd $user
echo "$pass" | passwd --stdin $user &>/dev/null
if [ $? -eq 0 ];then
echo -e "${red_col}${user}${reset_col} create"
fi
fi
done
第3步:测试语法,并测试脚本的运行。
sh -n useradd.sh
chmod +x useradd.sh
./useradd.sh /tmp/user.txt
===============================================
案例:批量创建用户。
vi useradd3.sh
#!/bin/bash
while :
do
read -p "Please enter name & password & num & mode[add/del]:" name pass num mode
printf "user information:
-----------------------------
user name: $name
user passwd: $pass
user number: $num
user mode: $mode
-----------------------------
"
read -p "Are you sure?[y/n]:" action
if [ "$action" = "y" ];then
break
fi
done
case $mode in
add)
for i in $(seq -w $num)
do
user=${name}${i}
useradd $user
echo "$pass" | passwd --stdin $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is created"
fi
done
;;
del)
for i in $(seq -w $num)
do
user=${name}${i}
userdel -r $user &>/dev/null
if [ $? -eq 0 ];then
echo "$user is deleted"
fi
done
;;
*)
echo "Program exit"
exit 0
;;
esac
-----------------------------
案例:用for的c风格写批量ping的基本脚本.
vi pi2.sh
#!/bin/bash
for ((i=1;i<=10;i++))
do
{
ip=192.168.100.$i
ping -c 1 -W1 $ip |grep ttl
}&
done
wait
echo "finish..."
=============================
案例:while自动切换网关。
vi gw.sh
#!/bin/bash
gw1=192.168.100.3
gw2=192.168.100.2
while :
do
ip r del default
ip r add via $gw1
while ping -c1 $gw1 &>/dev/null
do
sleep 1
done
ip r del default
ip r add default via $gw2
until ping -c1 $gw1 &>/dev/null
do
sleep 1
done
done &