一、实验目的:
使学生熟悉一种简单的指定用户的监测方法,熟悉UNIX的基本SHELL程序设计方法和使用技巧,包括:
(1)命令行参数检测
(2)用户变量
(3)while循环控制
(4)暂停进程(sleep)
二、实验原理:
(1)SHELL程序的主要用途
在SHELL程序中不仅仅可以使用命令的集合,而且可以安排自动化处理过程,因此可以通过编写SHELL程序使大量的任务执行实现自动化。SHELL比较擅长完成系统管理任务,尤其适合完成那些易用性、可维护性和便携性比执行效率更优先的任务。我们可以使用任意一种文本编辑器完成SHELL程序的编写,在SHELL编程中要遵循一定的程序设计规则和变量使用规则。
(2)SHELL程序的执行与调试
在bash的SHELL程序设计中,程序必须以下面的行开始:
#!/bin/bash |
这里符号#!用来告诉系统,后面给出的参数是用来执行该文件的程序。
利用vi,gedit等文本编辑器编写Shell脚本的格式是固定的,如下:
#!/bin/sh #comments Your commands go here |
filename.sh,文件名后缀sh表明这是一个Bash脚本文件
当编辑完一个SHELL脚本后,要使该脚本能够执行,还必须使该脚本文件具有可执行权。需要执行命令:
chmod +x filename |
在shell程序中,以#开头到一个行结束的句子表示注释信息。建议大家在编写shell程序时养成添加注释的习惯,因为注释不仅能给其他需要熟悉该程序的人以帮助,也能给出脚本编写者设计原理的提示。
进行shell程序设计时,必定会用到变量。Shell编程中使用的变量有自己的特色,即所有的变量都是由字符串组成的,而且对变量无须进行声明,可直接进行变量赋值操作。
(3)SHELL程序注意事项
SHELL编程中除了需要遵守一些规则外,还有一些注意事项,如果做得好会对编程有促进,这里列出几条仅供大家参考,更多的内容还需自己通过编程积累。
因为LINUX中命令使用的是小写字符,因此在SHELL编程中可以使用大写字符表示变量以示区别。
在SHELL语句中加入必要的注释,以便以后阅读和维护,注释以”#”开头。
对SHELL变量进行数字运算时,使用乘法符号”*”时,要用转义符”\”进行转义。例子:multiplication=` expr $j \* $j`
由于SHELL对命令中多余的空格不进行任何处理,因此程序员可以利用这一特性调整程序缩进格式,达到增强程序可读性的效果。
在对函数命名时最好能使用有含义且容易理解的名字,即使函数名能够比较准确地表达函数所完成的任务。同时建议对于较大的程序要建立函数命名和变量命名对照表。
如果一行未完成,可以在行尾加上“这个符号 表明下一行与此行会合并为同一行。
(4)SHELL简单调试
最简单的调试命令当然是使用echo命令。可以使用echo在任何怀疑出错的地方打印任何变量值。另外还可以利用Bash中提供的选项进行检查
-n,读一遍脚本中的命令但不执行,用于检查脚本中的语法错误。
-v,一边执行脚本,一边将执行过的脚本命令打印到标准输出。
-x,提供跟踪执行信息,将执行的每一条命令和结果依次打印出来。该选项会显示刚刚执行的命令及参数。用户可以通过set命令打开-x选项或在启动Shell使用-x选项将Shell设置成跟踪模式。
使用这些选项有三种方法(注意:避免几种调试选项混用)
1.在命令行提供参数:$sh -x script.sh
2.脚本开头提供参数:#!/bin/sh -x
3.在脚本中用set命令启用or禁用参数:其中set -x表示启用,set +x表示禁用。
(4)Sh和bash的区别
Linux系统中的/bin/sh本是bash的符号链接,鉴于bash过于复杂,有人把bash从NetBSD移植到Linux并更名为dash,并建议将/bin/sh指向它,以获得更快的脚本执行速度。Dash Shell比Bash Shell小的多,符合POSIX标准。
因为bash是sh的增强版本,在我们平常实地操作的时候如果sh这个命令不灵了我们应当使用bash。
(5)用户切换操作
1.sudo su //切换到root权限(但不是root用户)
2. adduser tongxue1 增加一个同学1
3. login tongxue1 登录同学1
4 这个时候使用who命令来查看 就会发现多了一个登录账户 tongxue1了
三、实验内容:
编写一个用户监测程序usr_monitor, 其运行格式为:
usr_monitor username |
其中username是用户指定的任意一个用户名。
程序运行时首先列出当前系统中的已登录用户的名单,再检查指定用户是否已登录。如果已登录,则显示相应信息;如果未登录,则等待该用户登录,直到指定用户登录进入系统为止。具体步骤如下所示:
(1)根据变量$#的值检查命令行上是否有一个用户名,如果有则继续运行;如果没有或多于一个用户名则输出提示信息:
Usage: usr_monitor username
(2)运行who命令,并将运行结果中的用户名字段截取下来,保存到一个用户变量中。
(3)echo命令显示该变量的值,即当前系统中的用户名单。
(4)判断用户名单中是否包含命令行上指定的用户,如果有则输出提示信息:user [username] is logon,并退出程序。
(5)如果用户名单中没有包含命令行上指定的用户,则输出提示信息:waiting user [username] …,光标停留在省略号后面。
(6)使用while循环,用sleep命令每隔5秒钟检查指定用户是否已登录系统。检测方法与步骤2相同。
(7)如果指定用户未登录,则一直等待下去;如果指定用户已登录,则在省略号后面接着输出提示信息: [username] is log on,退出循环,并结束程序。
参考代码如下:
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage: usr_monitor username"
exit 1
fi
username=$1
users=$(who | awk '{print $1}')
echo "Current logged-in users:"
echo "$users"
while true; do
users=$(who | awk '{print $1}')
if echo "$users" | grep -w "$username" > /dev/null; then
echo "User [$username] is logged on"
break
else
echo "Waiting for user [$username] ..."
sleep 5
fi
done
echo "User [$username] is logged on. Exiting."