循环

1. 循环语句语法
(1) for循环
	for variable in varlist
	do
		statement
	done
	或C语言类型的循环
	for((exp1;exp2;exp3))
	do
		statement
	done
(2) while循环
	while condition
	do
		statement
	done

(3) until循环
	while  condition
	do
		statement
	done
(4) 使用$0循环
	#!/bin/bash

	clear
	date "+%Y-%m-%d %H:%M:%S"
	sleep 1
	sh $0
	-----------------------
	循环次数较少可以使用

(5) 跳出循环
	break、continue、exit
	continue	--跳过某一个条件,继续执行其他循环
	break		--跳出循环,不再循环,往下执行代码
	exit		--退出程序
	
	exit退出时可以返回一个状态信息,范围是0-255,一般情况0是正常退出。

	#!/bin/bash

	for (( i=1; i<=100; i++ ))
	do
		    if (( $i%2  == 0 ))
		    then
		            continue;
		    else
		            echo -n "$i "
		    fi
	done
		    echo

	------------------------
	#!/bin/bash

	for (( j=1; ; ))
	do
		echo -n "$j "
		let j++

		if [ $j -eq 100 ];then
			break	
			#exit
		fi

	done
		echo 
		echo "end"

	-------------------------
	#!/bin/bash

	if [ $# -ne 1 ];then
		    echo "Usage: sh $0 filename"
		    exit 1
	fi

	if [ ! -e $1 ];then
		    exit 2
	fi

	
2. 循环实例			--做重复的事
2.1 	for 循环语句	
	do			--开始
	done			--完成
	
	格式:
	for  var    in  1 2 3 4 5 
	do
		statement
	done
	
	类似于C语言的方式:

	for (( var=1 ; var < 6 ; var++ ))				--((开始条件;结束条件;变化的条件))
	do
		statement
	done

	for (( var=5; var >0 ; var-- ))
	do
		statement
	done

2.1.1 for循环举例

	for  i   in 1 2 3 4 5
	do
	        echo -ne "$i\n"--如果不使用-n参数,默认会一个数字打印一行,-e参数代表后面如果使用\n(换行),\t(制表符)等这种字符时会生效,所以这句和echo $i效果一样
	done

	for i  in `seq 100`		--产生1到100的序列,默认从1开始
	do
	        echo -n $i
	done

	for i in $(seq 100)		--也是产生1到100的序列,这是另一种写法
	do
	        echo -n $i
	done

	for i in `seq 50 100`	--从50到100,50是开始,100是结束
	do
	        echo -n $i
	done
	echo

	for i in `seq 1 2 100`	--从1开始到100,中间的2为步长
	do
	        echo -n $i
	done
	echo

	for i in `seq 100 -2 51`
	do
	        echo -n "$i "
	done
	echo

	for i in {50..100}
	do
	        echo -n $i
	done
	echo

	for i in {50..100..2}	--步长是在最后
	do
	        echo -n $i
	done
	echo

	for i in {100..50..-2}
	do
	        echo -n $i
	done
	echo

	for i in {100..-50}
	do
	        echo -n $i
	done
	echo

	for i in {a..z}
	do
	        echo -n $i
	done
	

	for (( i=50 ;i <101; i+=2 ))
	do
	        echo -n $i
	done
	echo
	
	# echo {000..100}
	# seq -w 1 100 | xargs
计算1到100的和

	#!/bin/sh

	sum=0
	for (( i=1; i<=100; i++ ))
	do
		    sum=$[$sum + $i];
	done
		    echo $sum
	-----------------------------
	#!/bin/sh
	sum=0
	for i in {1..100}
	do
		    sum=$[$sum+$i]
	done
	echo $sum



	写一个脚本,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里(如果例举整个网段的254个IP花的时间比较长,可以只分类192.168.1.10到192.168.1.30)
	#!/bin/bash

	if [ -e /tmp/1.txt -a -e /tmp/2.txt ];then
		    rm /tmp/1.txt
		    rm /tmp/2.txt
	fi


	for i in 192.168.1.{1..30}
	do
		    ping $i -c 2 &> /dev/null

		    if [ $? -eq 0 ];then
		            echo $i >> /tmp/1.txt
		    else
		            echo $i >> /tmp/2.txt
		    fi
	done
		    echo "ping通的ip是: "
		    cat /tmp/1.txt
		    echo "=============================="
		    echo "ping不通的ip是: "
		    cat /tmp/2.txt
2.2 while
	用于不定次数的循环,或死循环

	while  [条件]
	do
		statement
	done

	----------------------
	主要用户不定次数的循环:

	#!/bin/bash

	name=0
	uid=0
	gid=0
	# read一次读一行,将一行的内容赋值给line变量,文件有多少行就循环多少次
	cat /etc/passwd | while read line
	do
		name=`echo $line | cut -d ":" -f1`
		uid=`echo $line | cut -d ":" -f3`
		gid=`echo $line | cut -d ":" -f4`
		echo "$name的uid是$uid,gid是$gid"
	done

	----------------------------

	求1+2+...+100的和
	#!/bin/bash

	i=1
	sum=0

	while (( i <=100 ))
	do
		    sum=$[$sum+$i]
		    let i++
	done
		    echo $sum



2.2.1 死循环四种:

	while true				--true是真的意思,条件永远成立,一直执行
	do
		statement
	done

	while :
	do
		statement
	done

	for (( ; ; ))			--分号不能少,表示空语句
	do
		statement
	done

	for ((i=1;;i++))
	do
		statement
	done

	-------------------------
	#!/bin/bash

	for (( ; ; ))
	do
		    clear
		    date "+%Y-%m-%d %H:%M:%S"
		    sleep 1
	done


2.3 until	循环	--直到满足条件就退出循环
	--使用很少
	实例
	用until实现打印1到5
	#!/bin/bash

	a=1
	until (( $a > 5 ))
	do
		    echo $a
		    let a++
	done

	echo "========================"

	i=1
	while (( $i <= 5 ))
	do
		    echo $i
		    let i++
	done


3. 随机数
	bash默认有一个$RANDOM的变量		使用set |grep RANDOM	查看上一次产生的随机数
	
	echo $RANDOM

	产生100内的随机数
	echo $[$RANDOM%101]

	产生0-1之间的随机数
	echo $[$RANDOM%2]

	产生1-2之内的随机数
	echo $[$RANDOM%2+1]

	产生50-100之内的随机数
	echo $[$RANDOM%51+50]

	产生三位数的随机数
	echo $[$RANDOM%900+100]

	
	随机产生100个电话号码:1350755xxxx
	#!/bin/sh

	for i in {1..100}
	do
		    echo 1350755$[$RANDOM%9000+1000]
			echo 135$[$RANDOM%9000+1000]$[$RANDOM%9000+1000]
	done


4. 循环嵌套			--循环里面还有循环,了解
	for (( ))
	do
		for (( ))
		do
			statement
		done
	done

	for (( ))
	do
		while [condition]
		do
			statement
		done
	done

	while [condition]
	do
		for (( ))
		do
			statement
		done
	done

	while [condition]
	do
		while [condition]
		do
			statement
		done
	done

	#!/bin/sh

	for (( i=0; i<5; i++ ))
	do
		    for (( j=0; j<i; j++ ))
		    do
		            echo -n "* "
		    done
		    echo 
	done
	
	* 
	* * 
	* * * 
	* * * *

	#!/bin/bash

	for (( i=0; i<5; i++ ))
	do
		    for (( j =0; j<5 ; j++ ))
		    do
		            echo -n "* "
		    done
		    echo 
	done

	* * * * * 
	* * * * * 
	* * * * * 
	* * * * * 
	* * * * * 

	写一个小闹钟的程序  (每秒都显示时间,当到了定时的时间,就循环打印5个*,间隔一秒)

	--可以替代at服务做一到时间就触发脚本,并且可以精确到秒

	#!/bin/bash
	while true
	do
	        now=`date +%H:%M:%S`
	        echo $now
	        sleep 1
	        clear
	        if [ "$1" == "$now" ];then
				echo "时间到了" 
		       	/etc/init.d/httpd restart
	                	break		--在这里是表示打完*后,跳出循环,继续执行循环体后面的代码;如果换成exit则表示直接退出脚本
	        fi
	done

	echo
	echo 'it is time'
1.用Shell编程,判断一文件是不是字符设备文件,如果是将其拷贝到/root目录下。
	#!/bin/bash

	# 传递一个参数

	if [ ! $# -eq 1 ];then
		echo "请传入一个参数"
		exit
	fi

	# 先判断文件是否存在,文件存在就判断是否是字符设备文件,文件不存在退出程序
	if [ -e $1 ];then
		if [ -c $1 ];then
		cp -a $1 /root/

		        if [ $? -eq 0 ];then
		                echo "拷贝完成"
		        else
		                echo "拷贝出错"
		        fi
		fi
	else
		echo "文件不存在"       
		exit
	fi


2.设计一个shell程序,添加一个新组为class1,然后添加属于这个组的30个用户,用户名的形式为stdxx,其中xx从01到30。
	#!/bin/bash

	groupadd class1 &> /dev/null

	if [ $? -eq 0 ];then
		for user in std{01..30}
		do
		        id $user &> /dev/null

		        # 判断$user是否存在     
		        if [ $? -eq 0 ];then
		                # $user存在     
		                userdel -r $user
		                useradd -G class1 $user
		        else
		                # 不存在
		                useradd -G class1 $user
		        fi
		done
	else
		echo "class1组已经存在"
		read -p "你是否要删除已经存在的组class1[y/n]" yn

		if [ "$yn" = "y" ];then
		        groupdel class1
		        groupadd class1

		for user in std{01..30}
		do
		        id $user &> /dev/null

		        # 判断$user是否存在     
		        if [ $? -eq 0 ];then
		                # $user存在     
		                userdel -r $user
		                useradd -G class1 $user
		        else
		                # 不存在
		                useradd -G class1 $user
		        fi
		done
		else
		        echo "退出程序"
		        exit
		fi
	fi


3.编写shell程序,实现自动删除50个账号的功能。账号名为stud1至stud50。
	#!/bin/bash

	for user in stud{1..50}
	do
		id $user &> /dev/null

		if [ $? -eq 0 ];then
		        userdel -r $user
		fi
	done


4.在根目录下创建四个文件m1.txt,m2.txt,m3.txt,m4.txt,用Shell编程,实现自动创建m1,m2,m3,m4四个目录,并将m1.txt ,m2.txt,m3.txt,m4.txt 四个文件分别拷贝到各自相应的目录下
	#!/bin/bash

	touch /m{1..4}.txt

	for i in {1..4}
	do
		mkdir -p /m${i}
		cp -a /m${i}.txt /m${i}
	done



5.设计一个Shell程序,在/userdata目录下建立50个目录,即user1~user50,并设置每个目录的权限,其中其他用户的权限为:读;文件所有者的权限为:读、写、执行;文件所有者所在组的权限为:读、执行(rwxr-xr--754)

	#!/bin/bash

	for i in user{1..50}
	do
		mkdir -p /userdata/$i
	done
		chmod 754 /userdata/ -R


6.设计一个shell程序,备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式yymmdd_etc,yy为年,mm为月,dd为日。
	
	#!/bin/bash

	YY=`date +%Y`
	MM=`date +%m`
	DD=`date +%d`

	mkdir -p /root/bak

	tar zcf /root/bak/${YY}${MM}${DD}_etc.tar.gz /etc/  &> /dev/null


7.gameser这个服务启动命令为./gameser服务,请写一个脚本,当服务宕掉,脚本自动拉起gameser服务。

	使用系统自带的软件apache做实验

	#!/bin/bash

	while true
	do
		#如何判断一个程序是否在运行?
		pid=`pidof httpd | cut -d " " -f1`

		#判断pid变量是否为空
		if [ -z $pid ];then
		        # pid为空,服务未启动,将其启动
		        service httpd start
		fi

		sleep 3
	done

	-----------------------
	gameser程序:

	#!/bin/bash

	while true
	do
		#如何判断一个程序是否在运行?
		pid=`pidof gameser | cut -d " " -f1`

		#判断pid变量是否为空
		if [ -z $pid ];then
		        # pid为空,服务未启动,将其启动
		        ./gameser
		fi

		sleep 3
	done

  

  

  

  

posted @ 2019-12-18 22:44  MlxgzZ  阅读(277)  评论(0编辑  收藏  举报