Bash loop脚本编程

在Linux / UNIX操作系统下,如何使用bash for loop重复执行某些任务?

for file in "*.list"; 
do 
    if [ -e $file ]; 
    then 
        cat $file | grep ^Hostname[0-9]; 
    fi
done
示例正则表达式 例子 说明  [abc] 匹配 “a”、“b”、“c” 之一  [a-z] 匹配从 “a” 到 “z” 的任何一个小写字符  [A-Z] 匹配从 “A” 到 “Z” 的任何一个大写字符  [0-9] 匹配从 0 到 9 的任何一个数字  [^0-9] 匹配任何除了 0 到 9 数字范围内的任何字符  [-0-9] 匹配从 0 到 9 的任何数字,或者是短横线(-)  [0-9-] 匹配从 0 到 9 的任何数字,或者是短横线(-)  [^-0-9]匹配除从 0 到 9 的数字和短横线(-)之外的任何字符  [a-zA-Z0-9] 匹配任何字符或数字
^ 符号(^)表示一行的开始;$ 符号($)表示一行的结束。


如何使用for语句设置无限循环?

如何使用三参数进行循环控制表达式?

“ for循环”是bash编程语言的语句,它允许重复执行代码。 for循环被归类为迭代语句,即bash脚本中进程的重复。

例如,您可以运行UNIX命令或任务5次,或使用for循环读取和处理文件列表。 可以在shell提示符下或在shell脚本本身内使用for循环。

for循环语法
数字范围的语法如下:

for VARIABLE in 1 2 3 4 5 .. N
do
    command1
    command2
    commandN
done

for VARIABLE in file1 file2 file3
do
    command1 on $VARIABLE
    command2
    commandN
done

 
for OUTPUT in $(Linux-Or-Unix-Command-Here)
do
    command1 on $OUTPUT
    command2 on $OUTPUT
    commandN
done
实例
这种for循环的特征是计数。范围由开始(#1)和结束数字(#5)指定。for循环为项列表中的每个成员执行一系列命令。下面是BASH中的一个典型示例,它使用for循环显示欢迎消息5次

#!/bin/bash
for i in 1 2 3 4 5
do
   echo "Welcome $i times"
done
有时您可能需要设置一个step值(例如允许一个按两个s计数或向后计数)。最新的bash 3.0+版本内置了对设置范围的支持

#!/bin/bash
for i in {1..5}
do
   echo "Welcome $i times"
done
Bash v4.0+内置了对使用{START..END..增量}语法

#!/bin/bash
echo "Bash version ${BASH_VERSION}..."
for i in {0..10..2}
  do 
     echo "Welcome $i times"
 done
输出结果:

Bash version 4.0.33(0)-release...
Welcome 0 times
Welcome 2 times
Welcome 4 times
Welcome 6 times
Welcome 8 times
Welcome 10 times
seq命令(过时的)
警告!seq命令打印一个数字序列,由于历史原因,它出现在这里。以下示例仅适用于较旧的bash版本。建议所有用户(bash v3.x+)使用上述语法。

seq命令可按如下方式使用。seq中的一个典型例子如下

#!/bin/bash
for i in $(seq 1 2 20)
do
   echo "Welcome $i times"
done
没有很好的理由使用诸如seq之类的外部命令来计数和递增for循环中的数字,因此建议您避免使用seq。内置命令是快速的。

三元表达式bash for循环语法
这种for循环与C编程语言有一个共同的传统。其特征是一个三参数循环控制表达式;由一个初始化器(EXP1)、一个循环测试或条件(EXP2)和一个计数表达式(EXP3)组成。

for (( EXP1; EXP2; EXP3 ))
do
    command1
    command2
    command3
done
下面是bash中的一个典型的三元表达式示例

#!/bin/bash
for (( c=1; c<=5; c++ ))
do  
   echo "Welcome $c times"
done
输出结果:

Welcome 1 times
Welcome 2 times
Welcome 3 times
Welcome 4 times
Welcome 5 times
如何使用for作为无限循环?
可以使用空表达式创建Infinite for循环,比如

#!/bin/bash
for (( ; ; ))
do
   echo "infinite loops [ hit CTRL+C to stop]"
done
带断点的条件退出
您可以在for循环中使用break语句提前退出。您可以使用break从FOR、WHILE或UNTIL循环中退出。for循环中的General break语句

for I in 1 2 3 4 5
do
  statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
  statements2
  if (disaster-condition)
  then
    break              #Abandon the loop.
  fi
  statements3          #While good and, no disaster-condition.
done
以下shell脚本将通过所有存储在/ etc目录中的文件。 找到/etc/resolv.conf文件时,将跳出for循环。

#!/bin/bash
for file in /etc/*
do
    if [ "${file}" == "/etc/resolv.conf" ]
    then
        countNameservers=$(grep -c nameserver /etc/resolv.conf)
        echo "Total  ${countNameservers} nameservers defined in ${file}"
        break
    fi
done
使用continue语句
若要继续封闭FOR、WHILE或UNTIL循环的下一个迭代,请使用continue语句。
for I in 1 2 3 4 5
do
  statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
  statements2
  if (condition)
  then
    continue   #Go to next iteration of I in the loop and skip statements3
  fi
  statements3
done
此脚本备份命令行中指定的所有文件名。如果.bak文件存在,它将跳过cp命令。

#!/bin/bash
FILES="$@"
for f in $FILES
do
        # if .bak backup file exists, read next file
    if [ -f ${f}.bak ]
    then
        echo "Skiping $f file..."
        continue  # read next file and skip the cp command
    fi
        # we are here means no backup file exists, just use cp command to copy file
    /bin/cp $f $f.bak
done
放在一起
Bash for循环对于自动化IT中的重复任务非常有用。让我们看看如何在多个Linux或Unix服务器上运行一个简单的命令(例如正常运行时间)

for s in server1 server2 server3
do
    ssh vivek@${s} "uptime"
done
或者将echo命令与命令替换合并,如下所示

for s in server1 server2 server3
do
    echo "Server ${s}: $(ssh vivek@${s} uptime)"
done
输出结果

Server server1:  09:34:46 up 12 days, 21:57,  0 users,  load average: 0.08, 0.09, 0.09
Server server2:  09:34:50 up 17 days,  2:30,  0 users,  load average: 0.03, 0.03, 0.00
Server server3:  09:34:53 up 17 days,  2:31,  0 users,  load average: 0.04, 0.04, 0.00
在此标准bash for loop示例中,如果我们有基于Debian / Ubuntu的服务器,我们将使用yum命令或apt命令/ apt-get命令更新所有基于CentOS / RHEL的服务器:

## CENTOS/RHEL example (for fedora replace yum with dnf) ##
for s in server0{1..8}
do
    echo "*** Patching and updating ${s} ***"
    ssh root@${s} -- "yum -y update"
done
这是简单但有用的shell脚本示例

#!/usr/bin/env bash
# Purpose: Update all my Linode servers powered by Debian/Ubuntu Linux
# Author: Vivek Gite under GPL v2.x+
# ----------------------------------------
log="/tmp/apt-get.log"
>"${log}"
for s in ln.cbz0{1..5}
do 
   echo "Updating and patching $s, please wait..." | tee -a "${log}"
   ssh root@${s} -- apt-get -q -y update >/dev/null
   ssh root@${s} -- DEBIAN_FRONTEND=noninteractive apt-get -y -q upgrade >>"${log}"
done
echo "Check $log file for details."
了解为什么我们使用DEBIAN_FRONTEND apt-get变量来避免更新期间出现任何提示。 最好是出于自动化目的设置ssh密钥或从Linux / Unix cron作业运行脚本。

总结
您通过各种示例学习了如何使用bash for loop。 For循环可以节省时间,并可以帮助您自动完成微小的任务。 但是,对于复杂的IT自动化任务,您应该使用Ansible,Salt,Chef,pssh等工具。 

 

上一篇:Todos案例(一)——业务分析 & 基本布局


下一篇:java 实现跳表(skiplist)及论文解读