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   [email protected]

ping  -c 4  127.0.0.1

;;

2)

#ssh   [email protected]

ping  -c 4 127.0.0.2

;;

3)

#ssh   [email protected]

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 <

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批量创建用户。

第1步:准备用户名单文件。

cat  > /tmp/user.txt <

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 &