command_list_n ;; ]
esac
其中,expr可以是变量、表达式或shell命令等,模式为expr的取值。通常一个模式可以是expr的多种取值,使用或(|)连接。模式中还可以使用通配符,星号(*)表示匹
配任意字符值,问号(?)表示匹配任意一个字符,[..]可以匹配某个范围内的字符。
在case分支结构中,首先计算expr的值,然后根据求得的值查找匹配的模式,接着执行对应模式后面的命令序列,执行完成后,退出case结构。需要注意的是,在case结构的命令序列后面需要使用双分号(;;)分隔下一个模式。 例6-5 使用case语句编写程序,根据上网地址的不同为计算机设置不同的IP地址参数。 #!/bin/bash
#an example script of case clear
echo \ read nettype case $nettype in home|h|H )
/sbin/ifconfig eth0 192.168.0.118 netmask 255.255.255.0 /sbin/route add default gw 192.168.0.1 ;; office|o|O)
/sbin/ifconfig eth0 192.168.1.58 netmask 255.255.255.0 /sbin/route add default gw 192.168.1.1 ;; *)
echo \ exit ;; esac
echo “Success!!!”
本例程中,如果用户输入home、h或H则表示上网地点是在家中,此时IP地址为192.168.0.118,网络掩码为24,默认网关为192.168.0.1。如果用户输入office、o或O则表示上网地点是在办公室内,此时IP地址为192.168.1.118,网络掩码为24,默认网关为192.168.1.1。其他的输入无效,并给出提示“input error!”。其中ifconig和route命令在后面的章节中将详细介绍。 3.for循环结构
for循环用于预先知道循环执行次数的程序段中,它是最常用的循环结构之一。for的格式如下: for var [ in value_list ] do
command_list done
其中,value_list是变量var需要取到的值,随着循环的执行,变量var需要依次从value_list中的第一个值,取到最后一个值。do和done结构之间的command_list是循环需要执行的命令序列,变量var每取一个值都会循环执行一次command_list中的命令。同样中括号部分为可选部分,如果省略了该部分,bash会从命令行参数中为var取值,即等同于“in $@”。
例6-6 使用for语句编写程序,向系统添加10个用户,其名称分别是student1、student2、?student10。
#!/bin/bash
# an example script of for for i in [ 1 – 10 ] do fi done
由于在Linux中adduser命令会在/home目录下创建与用户同名的子目录作为用户的主目录,所以,该例程首先检查/home目录下是否存在与student1、student2、...student10同名的子目录,如果存在则将其重命名为stu1、stu2、?stu10,然后在执行创建用户的任务,并且用户的初始口令与用户名相同。 4.while和until循环结构
while和until循环结构的功能基本相同,主要用于循环次数不确定的场合。while的格式如下: while expr do done
until的格式如下: until expr do done
从格式上看,二者的使用方法完全相同,但是二者对循环体执行的条件恰恰相反。在while循环中,只有expr的值为真时,才执行do和done之间的循环体,直到expr取值为假时退出循环。而在until循环中,只有expr的值为假时,才执行do和done之间的循环体,直到expr取值为真时退出循环。
command_list command_list
adduser student$i > /dev/null 2>$1 echo \
echo \if [ -d /home/student$i ] ; then
echo \
echo \mv student$i stu$i
while循环示例 #!/bin/bash #an example script of while clear loop=0 while [ $loop –le 10 ] until循环示例 #!/bin/bash #an example script of until clear loop=0 until[ $loop –gt 10 ] do do let loop=$loop+1 echo \ done let loop=$loop+1 echo \ done 从上面的while和until循环的执行流程可以看出,expr的取值直接决定command_list的执行与否以及能否正常退出循环,因此通常在命令序列command_list中都存在修改expr取值的命令。否则while和until就无法退出command_list的执行循环,从而陷入死循环。通常,同一个问题如果可以使用while循环,就可以使用until循环。 例6-7 while和until循环结构示例。
上面两段程序都是完成对循环变量loop加1的任务,两段程序的输出结果完全相同。对比两个程序可以发现,只有循环条件的设置不同。
shell函数
和其他的高级程序设计语言一样,在bash中也可以定义使用函数。函数是一个语句块,它能够完成独立的功能,而且在需要的时候可以被多次使用。利用函数,shell程序将具有相同功能代码块提取出来,实现程序代码的模块化。在程序需要修改的时候,只需要修改被调用的函数,减少了程序调试和维护的强度。 在bash中,函数需要先定义后使用。函数定义的格式如下: [function] fun_name ( ) { }
其中,function表示下面定义的是一个shell函数,可以省略。fun_name就是定义的函数名。command_list就是实现函数功能的命令序列,称为函数体。函数一旦定义就可以被多次调用,而且函数调用的方法与shell命令的方法完全一致。函数调用的格式如下:
fun_name [param_1 param_2 ? param_n]
其中,fun_name是被调用的函数名,param_1、param_2、?param_n是调用时传递给函数的参数,各参数之间使用空格隔开。函数调用时是否需要传递参数,由函数的定义和功能决定。如果函数确实需要传递参数,此时可以使用$0、$1、?$n,以及$#、$*和$@这些特殊变量。其中$0存放的是命令行的命令名(也就是执行的shell脚本名),$1存放的是命令行中传递给命令的第一个参数,依次类推,
$n存放的是传递给命令的第n个参数。$#为传递给命令的参数的个数(不包括命令),$*和$@均用于存放传递给命令的所有参数,两者的区别在于$*把所用的参数作为一个整体,而$@则把所有的参数看作是类似于字符串数组一样,可以单独访问这些参数。
例6-8 向bash函数传递参数的示例。在bash脚本中定义函数,然后在该脚本时通过命令行传递参数。 #!/bin/bash
#an example script of function #fun1函数定义 function fun1 ( ) {
echo \ echo \echo \echo \count = 1 for param in $@ do
echo \
command_list
} clear
echo \let count=$count+1
fun1 $@
本例通过命令行参数$0向函数fun1传递执行的命令名,通过$*给函数fun1传递所有的命令行参数;通过$#给函数fun1传递命令行参数的个数;通过$@来访问命令行中的每个参数。 如果该例程保存为demo.sh,可以采用如下的命令行方式运行: ./demo.sh hello red hat linux
此时,$0存放“./demo”,$*和$@都存放“hello red hat linux”,$#参数为4。 函数的返回值用来给函数的调用者带回特定的变量值,shell
程序中的函数也可以有返回值,使用return命令可以从函数返回值。一般函数正常结束时返回真,即0,否则返回假,即非0值。return使用的格式如下: return [expr]
expr存在,0表示程序正常结束,非0值表示程序出错。如果expr省略,则以函数的最后一条命令的执行状态作为返回值。另外,测试函数的返回值的方法可以使用和shell命令的返回值相同的方法,即使用测试$?值,也可以采用直接测试命令函数的返回值。
shell程序跟踪:
和高级语言开发程序一样,在编写shell程序的开发过程中,出错是在所难免的,因此shell程序的调试就变得至关重要了。下面给出在6.2节中编写的addusers.sh脚本为例,给出在shell程序调试中的技巧。
在RedHat Linux 9的命令提示符下输入如下的命令开启sh程序的跟踪模式,这样sh程序在解释执行addusers.sh脚本的时候,启用单步执行的方式,如图右所示。
图中给出了adduser.sh脚本每步运行的结果,可以很好的判断程序执行的情况。
Linux网络配置 7.1 网络配置基础
7.2 使用命令工具配置网络参数 7.3 使用文件配置网络
1) ping命令
ping命令用于测试当前系统的网络是否连通。该命令能够不间断地向目标主机发送ICMP协议的数据包,目标主机接收到数据包后返回应答。用户可以在屏幕上看到 数据包返回的信息,并根据这些信息判断网络的连通状态。该命令的格式如下:
ping [选项] 目标主机名或IP地址 [root@myhost root]# ping –c 5 www.aust.edu.cn traceroute命令
该命令向目的主机发送数据包,每经过一个网关或路由就返回一行信息,内容包括网络或路由的主机名或IP地址、每次经过该网关或路由的时间(单位为ms)。系统默认的数据包长度为38字节,最大跳数(Hop)为30次。该命令格式如下:
traceroute [选项] 目的主机名或IP地址 3)netstat命令
netstat命令用于查看网络连接、路由表信息和网络接口的状态信息,其格式如下: nestat [选项]
常用参数及含义如表所示 参 数 -a -c -i -l -n -t -u -w -r -v 含 义 显示所有套接口,包括正在监听的 每个1秒刷新一次结果,直到用户终止 显示所有网络接口信息 显示处于监听状态的套接口信息 显示结果直接使用IP地址,而不使用域名 显示TCP协议的连接状况 显示UDP协议的连接状况 显示RAW协议的连接状况 显示当前核心路由表的信息 显示命令执行过程 使用netstat命令来查看当前路由表的详细信息。 在终端提示符下输入如下的命令,其执行结果如图所示。 [root@myhost root]# netstat -nr
远程登录工具