一、问题

1.1、环境
电脑环境:Windows 10;
JDK环境: Jdk1.8;
Docker版本:Server Version: 19.03.3

1.2、问题
如何在shell脚本中使用For循环?

二、解答

2.1、基本知识;

2.2、实战
1、用for循环打印1到15个数字;
①、首先我们了解下seq的用法:
seq是序列号的意思,在linux系统中输入:

seq 1 15

就可以打印1到15,这15个数字;
所以seq的格式就是:

seq startNum  endNum

截图如下:

shell for循环取redis value_cycle


如果,我们不写开始的数字,seq后面只有一个数字会怎么样呢?

seq 15

那么,我们同样会打印1到15,这15个数字,所以,seq默认是从1开始的;

shell for循环取redis value_linux_02


如果,我们不要从0开始,必须制定开始的数字:

shell for循环取redis value_linux_03


那么,这个间隔怎么控制呢?为什么每次都是以1递增呢?

对于增量,我们可以用这样的表达命令来控制:

seq startNum incrementNum endNum

shell for循环取redis value_cycle_04

②、如何使用for循环呢?for循环的格式是:
格式:

for 变量 in  字符串		
do			
    语句1		
done

实例:
1、用for循环打印1到15个数字;
我们新增一个testFor.sh的文件,内容如下(注意,in后面的,seq 15外面包裹的,不是单引号,而是Tab键上面的,Esc键下面的那个键,是反单引号,反单引号表示,包裹的内容是一个命令):

#!/bin/bash
#For循环
#格式:For 变量 in  字符串
#		    do
#			语句1
#			done

for i in `seq 15`
do
	echo "NUM is $i"
done

截图:

shell for循环取redis value_linux_05


那有朋友会问了,一定要单个变量一定要写i么?这个是不一定的,你可以自己命名,例如:

#!/bin/bash
#For循环
#格式:For 变量 in  字符串
#		    do
#			语句1
#			done

for item in `seq 15`
do
	echo "NUM is $item"
done

打印的结果是一样的;

2、打印1-100的和
①、这里补充一个知识,就是expr命令,这个命令是表达式的意思,express;express后面跟的是数学运算(符号和数字之间一定要有空格),例如,在Linux命令行输入:

expr 1 + 1

我们得到结果:

shell for循环取redis value_linux_06


减法:

shell for循环取redis value_cycle_07


乘法,乘法需要注意,乘法的乘号和星号是一样的,必须使用转义字符:反斜杠,否则系统会把【*】当成星号来理解:

shell for循环取redis value_for_08


如果没有转移字符,会报错:

shell for循环取redis value_linux_09


如果数字和运算符号之间没有空格,系统会将你输入的内容作为字符串来理解:

shell for循环取redis value_linux_10


计算1到100的实例代码如下:

#!/bin/bash
SUM=0
for((i=1;i<=100;i++))
do
	SUM=`expr $i + $SUM`
done
echo $SUM

截图:

shell for循环取redis value_linux_11


大家可以看到,上面的图片打印了两个结果,第一个结果是expr表达式里,加号左右没有空格,他就将表达式当成字符串来拼接了,而第二个结果才是最终的结果;

利用这个字符串拼接的这个特性,我们可以修改下上面的内容:

#!/bin/bash
SUM=0
EXPR=0
for((i=1;i<=100;i++))
do
	EXPR=`expr $i+$EXPR`
	SUM=`expr $i + $SUM`
done
echo "$EXPR = $SUM"

我们可以将计算公式打印出来:

shell for循环取redis value_shell_12


还要注意的是,我们这次,没有使用for i in NUM这种表达式;而是使用了Java代码中最常见的for循环表达式的写法,那么Java中,其他for循环表达式,shell能否识别并执行呢?我们试了试,好像是不行的,大家可以自己试试;

3、知道某些共性的文件,然后批量打包,比如将我所有的shell脚本打包:
代码:

#!/bin/bash
for i in `find ./ -name "*.sh" `
do
	tar -czf 2020-01-05.tgz $i
done
echo "shell script is compressed at [`pwd`] "

截图:

shell for循环取redis value_for_13


这里,我们可以看到,我们将所有.sh结尾的shell脚本都打包到压缩包2020-01-05.tgz里面去了;for循环的反单引号是执行命令的意思,我们用find命令去查找,查找的目录是当前目录(./),查找的依据是根据名字(-name);tar命令是打包的命令,-czf是tar的打包命令参数,具体的tar打包命令

然后我们新增一个tarTemp文件夹(mkdir tarTemp),然后把打包的tgz文件解压到tarTemp文件夹里:

tar -xzf 2020-01-05.tgz  -C ./tarTemp/

然后我们到tarTemp文件夹里,发现,只有最后一个shell脚本,其他的脚本都没有,很明显,这是被最后一个脚本给覆盖了;

shell for循环取redis value_cycle_14


那么,我们该如何改脚本呢?

我们写一个if判断条件,如果不存在这个包,我们就创建一个新的压缩包,如果存在了,我们就向这个压缩包里追加新的文件:

#!/bin/bash
for i in `find ./ -name "*.sh" `
do
	if [[ -z 2020-01-05.tgz ]]; then
		tar -cvf 2020-01-05.tgz $i
	else
		tar -rvf 2020-01-05.tgz $i
	fi
	
done
echo "shell script is compressed at [`pwd`] "

截图(tar命令会将压缩的文件都打印出来):

shell for循环取redis value_cycle_15


然后,我们再去tarTemp文件夹里看看,我们是否压缩完毕(tar命令中的-C表示解压到某个目录):

shell for循环取redis value_for_16


成功!