shell读书笔记7

12、while 命令
12.1、while 的基本格式
while命令的格式是:

	while test command
	do
	other commands
	done
	while命令中定义的test command和if-then语句(参见第12章)中的格式一模一样。可
	以使用任何普通的bash shell命令,或者用test命令进行条件测试,比如测试变量值
	$ cat test10
	#!/bin/bash
	# while command test
	var1=10
	while [ $var1 -gt 0 ]
	do
	echo $var1
	var1=$[ $var1 - 1 ]
	done
	$ ./test10
	10
	9
	8
	7
	6
	5
	4
	3
	2
	1
	$

12.2、使用多个测试命令
while命令允许你在while语句行定义多个测试命令。只有最后一个测试命令的退出状态码
会被用来决定什么时候结束循环。
每个测试命令都出现在单独的一行上

13、until 命令
until命令和while命令工作的方式完全相反。until命令要求你指定一个通常返回非零退
出状态码的测试命令。只有测试命令的退出状态码不为0,bash shell才会执行循环中列出的命令。
一旦测试命令返回了退出状态码0,循环就结束了。
until命令的格式如下。

	until test commands
	do
		other commands
	done
	你可以在until命令语句中放入多个测试命令。只有最后一个命令的退出状态码决定了bash shell是否执行已定义的other commands。
	下面是使用until命令的一个例子。
	$ cat test12
	#!/bin/bash
	# using the until command
	var1=100
	until [ $var1 -eq 0 ]
	do
	echo $var1
	var1=$[ $var1 - 25 ]
	done
	$ ./test12
	100
	75
	50
	25
	$

14、循环处理文件数据
通常必须遍历存储在文件中的数据。这要求结合已经讲过的两种技术:
 I、使用嵌套循环
 II、修改IFS环境变量
通过修改IFS环境变量,就能强制for命令将文件中的每行都当成单独的一个条目来处理,
即便数据中有空格也是如此。一旦从文件中提取出了单独的行,可能需要再次利用循环来提取行
中的数据。
典型的例子是处理/etc/passwd文件中的数据。这要求你逐行遍历/etc/passwd文件,并将IFS
变量的值改成冒号,这样就能分隔开每行中的各个数据段了。

	#!/bin/bash
	# changing the IFS value
	IFS.OLD=$IFS
	IFS=$'\n'
	for entry in $(cat /etc/passwd)
	do
		echo "Values in $entry –"
		IFS=:
		for value in $entry
		do
			echo " $value"
		done
	done
	$
这个脚本使用了两个不同的IFS值来解析数据。第一个IFS值解析出/etc/passwd文件中的单独
的行。内部for循环接着将IFS的值修改为冒号,允许你从/etc/passwd的行中解析出单独的值。
在运行这个脚本时,你会得到如下输出。
	Values in rich:x:501:501:Rich Blum:/home/rich:/bin/bash -
	rich
	x
	501
	501
	Rich Blum
	/home/rich
	/bin/bash
	Values in katie:x:502:502:Katie Blum:/home/katie:/bin/bash -
	katie
	x
	506
	509
	Katie Blum
	/home/katie
	/bin/bash
内部循环会解析出/etc/passwd每行中的各个值。这种方法在处理外部导入电子表格所采用的
逗号分隔的数据时也很方便。

15、控制循环
有两个命令能帮我们控制循环内部的情况:
I、break命令
 II、continue命令

16、处理循环的输出
最后,在shell脚本中,你可以对循环的输出使用管道或进行重定向。这可以通过在done命令
之后添加一个处理命令来实现。

	for file in /home/rich/*
	do
	if [ -d "$file" ]
	then
	echo "$file is a directory"
	elif
	echo "$file is a file"
	fi
	done > output.txt
shell会将for命令的结果重定向到文件output.txt中,而不是显示在屏幕上

考虑下面将for命令的输出重定向到文件的例子。
	$ cat test23
	#!/bin/bash
	# redirecting the for output to a file
	for (( a = 1; a < 10; a++ ))
	do
		echo "The number is $a"
	done > test23.txt
	echo "The command is finished."
	$ ./test23
	The command is finished.
	$ cat test23.txt
	The number is 1
	The number is 2
	The number is 3
	The number is 4
	The number is 5
	The number is 6
	The number is 7
	The number is 8
	The number is 9
	$
这种方法同样适用于将循环的结果管接给另一个命令。
	$ cat test24
	#!/bin/bash
	# piping a loop to another command
	for state in "North Dakota" Connecticut Illinois Alabama Tennessee
	do
	echo "$state is the next place to go"
	done | sort
	echo "This completes our travels"
	$ ./test24
	Alabama is the next place to go
	Connecticut is the next place to go
	Illinois is the next place to go
	North Dakota is the next place to go
	Tennessee is the next place to go
	This completes our travels

17、实例
17.1、查找可执行文件
当你从命令行中运行一个程序的时候,Linux系统会搜索一系列目录来查找对应的文件。这
些目录被定义在环境变量PATH中。如果你想找出系统中有哪些可执行文件可供使用,只需要扫
描PATH环境变量中所有的目录就行了。如果要徒手查找的话,就得花点时间了。不过我们可以
编写一个小小的脚本,轻而易举地搞定这件事。
首先是创建一个for循环,对环境变量PATH中的目录进行迭代。处理的时候别忘了设置IFS
分隔符。

	IFS=:
	for folder in $PATH
	do

现在你已经将各个目录存放在了变量$folder中,可以使用另一个for循环来迭代特定目录
中的所有文件。

	for file in $folder/*
	do
最后一步是检查各个文件是否具有可执行权限,你可以使用if-then测试功能来实现。
	if [ -x $file ]
	then
	echo " $file"
	fi

好了,搞定了!将这些代码片段组合成脚本就行了。

	$ cat test25
	#!/bin/bash
	# finding files in the PATH
	IFS=:
	for folder in $PATH
	do
	echo "$folder:"
	for file in $folder/*
	do
	if [ -x $file ]
	then
	echo " $file"
	fi
	done
	done
	$

运行这段代码时,你会得到一个可以在命令行中使用的可执行文件的列表。

	$ ./test25 | more
	/usr/local/bin:
	/usr/bin:
	/usr/bin/Mail
	/usr/bin/Thunar
	/usr/bin/X
	/usr/bin/Xorg
	/usr/bin/[
	/usr/bin/a2p
	/usr/bin/abiword
	/usr/bin/ac
	/usr/bin/activation-client
	/usr/bin/addr2line
	...
输出显示了在环境变量PATH所包含的所有目录中找到的全部可执行文件,数量真是不少!

17.2、创建多个用户账户
shell脚本的目标是让系统管理员过得更轻松。如果你碰巧工作在一个拥有大量用户的环境
中,最烦人的工作之一就是创建新用户账户。好在可以使用while循环来降低工作的难度。
你不用为每个需要创建的新用户账户手动输入useradd命令,而是可以将需要添加的新用户
账户放在一个文本文件中,然后创建一个简单的脚本进行处理。这个文本文件的格式如下:
userid,user name
第一个条目是你为新用户账户所选用的用户ID。第二个条目是用户的全名。两个值之间使用
逗号分隔,这样就形成了一种名为逗号分隔值的文件格式(或者是.csv)。这种文件格式在电子表
格中极其常见,所以你可以轻松地在电子表格程序中创建用户账户列表,然后将其保存成.csv格
式,以备shell脚本读取及处理。
要读取文件中的数据,得用上一点shell脚本编程技巧。我们将IFS分隔符设置成逗号,并将
其放入while语句的条件测试部分。然后使用read命令读取文件中的各行。实现代码如下:
while IFS=’,’ read –r userid name
read命令会自动读取.csv文本文件的下一行内容,所以不需要专门再写一个循环来处理。当
read命令返回FALSE时(也就是读取完整个文件时),while命令就会退出。妙极了!
要想把数据从文件中送入while命令,只需在while命令尾部使用一个重定向符就可以了。
将各部分处理过程写成脚本如下。

	$ cat test26
	#!/bin/bash
	# process new user accounts
	input="users.csv"
	while IFS=',' read -r userid name
	do
	echo "adding $userid"
	useradd -c "$name" -m $userid
	done < "$input"
	$

$input变量指向数据文件,并且该变量被作为while命令的重定向数据。users.csv文件内容
如下。

	$ cat users.csv
	rich,Richard Blum
	christine,Christine Bresnahan
	barbara,Barbara Blum
	tim,Timothy Bresnahan
	$

必须作为root用户才能运行这个脚本,因为useradd命令需要root权限。

	# ./test26
	adding rich
	adding christine
	adding barbara
	adding tim
	#

来看一眼/etc/passwd文件,你会发现账户已经创建好了。

	# tail /etc/passwd
	rich:x:1001:1001:Richard Blum:/home/rich:/bin/bash
	christine:x:1002:1002:Christine Bresnahan:/home/christine:/bin/bash
	barbara:x:1003:1003:Barbara Blum:/home/barbara:/bin/bash
	tim:x:1004:1004:Timothy Bresnahan:/home/tim:/bin/bash
	#

恭喜,你已经在添加用户账户这项任务上给自己省出了大量时间!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值