论文部分内容阅读
摘 要:Linux命令对于从未接触过命令行方式的学生来说,学习起来有一定的难度。在GNIIT课程的Linux单元实际教学中,运用shell编程对学生掌握枯燥、难以记忆的命令,能够起到较好的效果。本文通过对一个作为教学实例的shell程序进行剖析,说明经过精心设计的Shell程序有助于学生学习Linux命令。
关键词:Linux Shell 命令行 Shell编程
中图分类号:G434文献标识码:A 文章编号: 1673-1875(2009)03-105-02
一、问题的提出
在GNIIT课程中有关的Linux学习单元,其主要目的就是使学生了解Linux Shell,以便能够理解并实现模块中的项目所要求的远程连接到服务器进行用户权限管理,因此该单元涉及到大量的在Linux下进行系统管理的命令,使用命令行进行管理是Linux系统的特点,但这对于习惯了Windows的学生来说,是比较难适应的,原因有二,一是它改变了只需点击鼠标即可完成复杂功能的操作习惯,二是命令行方式下每条命令及其选项、参数的记忆确实让人头疼。因此找到一个能提高学生学习兴趣和学习效果的方法就显得非常重要。
孤立地学习和记忆每一条命令经常会令学生前学后忘,无法把所学的命令融会贯通,以致产生厌学、弃学的思想。针对于此,如果能够设计出一个解决基于实际问题的算法,编写出程序,把前后所学的命令串联起来,无疑会提高学生对所学命令的掌握,同时这也是GNIIT教学一直倡导的“学以致用”。
实现上述想法,可以利用Linux Shell编程。
二、相关知识
用户登录进入Linux系统时,可以进入基于X Window的图形视窗系统GDE完成很多工作,但是在服务器应用环境下的很多情况需要远程连接到服务器进行管理配置,而且使用命令行模式进行管理更加方便和简单,因此学习Linux,Shell的学习和使用是必不可少的一部分。
如果系统设置为不自动启动图形接口,那么用户登录时,实际进入了Shell①。Shell是什么呢?确切一点说,Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。
当用户使用Linux时是通过命令来完成所需工作的。一个命令就是用户和Shell之间对话的一个基本单位,它是由多个字符组成并以换行结束的字串。Shell解释用户输入的命令,就像DOS里的command.com一样②。
作为命令语言互动式地解释和执行用户输入的命令只是Shell功能的一个方面,Shell还可以用来进行程序设计,它提供了定义变量和参数的手段以及丰富的程序控制结构。使用Shell编程类似于DOS中的批处理文件,称为Shell script,又叫Shell程序或Shell命令文件。
三、一个Shell编程实例
Shell程序的设计,应该尽可能多地应用所学命令,同时还要兼顾学生的接受程度。来看下面这个问题。
1、问题
已将某班级学生某门课程考试成绩存储在score文件中。该文件的示例数据如下:
01 ZHANG 82
02 WANG 91
03 LI 76
......
在此文件中,字段定界符是‘ ’(空格)。不同的字段是学号,姓名,成绩。要求编写一个shell脚本,能够显示出成绩最高的学生的学号、姓名和成绩。例如:
The highest of the score is 91
2、题目设计目标
编写一个Shell程序解决这个问题,需要运用到以下命令:
1)vi编辑器创建和编辑文档;
2)创建和执行脚本;
3)标准输入与输出以及重定向;
4)grep和cut过滤器的特性和选项;
5)用管道结合多个命令;
6)创建变量;
7)计算表达式;
8)使用if构造执行基于条件的shell脚本;
9)用于执行重复任务的构造(while、for或until构造);
10)使用echo命令显示消息。
以上部分几乎涵盖了教材中所介绍的全部命令。当然,有些部分,比如上面所列的“创建变量”和“计算表达式”有多种方法和命令形式,取决于个人的喜好,同样,对于用于执行重复任务的构造(while、for或until构造),也由编写习惯决定。
3、问题分析
这是一个典型的求最大值/最小值问题。对于已经学习过1-2门程序设计语言课程的学生来说,不难理解如下算法:
结果变量y赋初值;
循环体
x=当前记录值
分支结构(x和y比较)
y中的值即所求结果
对于该算法,需要解决的问题包括:
1)初值。求最大值问题时,赋给变量y的初值为问题解域中的最小值。对于该题,问题解的集合为[0,100],因此初值赋为0。
2)循环体。这里采用for构造。Shell程序中for语句的用法为for(表达式1; 表达式2; 表达式3)
表达式1:起始比较位置。i=1
表达式2:循环结束判断。i≤记录数,而记录数可由表达式
j=$(grep -c ' ' score)
求得,因此表达式2即可写成
i<=$j
表达式3:增量。i=i+1
3)分支结构。对于求最大值问题,
if 当前记录值>y
then y=当前记录值
fi
4、该题的难点——如何定位“当前记录”
本题“数据库”中的“字段”分别是学号(“数字”)、姓名(“字母串”)和成绩(“数字”)。如果在典型的关系数据库系统中只需要把该“数据表”中的“学号”作为关键字即可定位记录,但是Shell命令中没有直接用于定位当前记录的命令,只能使用过滤器(通常是用管道结合多个过滤器命令)来找出每个记录区别于其他记录的个体特征,即“关键字段”。而使用过滤器命令不能只把学号作为“关键字段”。试考虑如下记录段
01 ZHANG 82
02 WANG 91
03 LI 76
用grep “1”是无法区分出数据库中的第1和第2条记录的。这时可以采取把“学号+姓名”作为关键字的办法,具体做法是通过cut命令过滤出score文件中的第一和第二列,存放到另一个文件match中。
cut -d ' ' -f1,2match
此时,match文件的内容为:
01 ZHANG
02 WANG
03 LI
在循环体中,当每次取欲比较的成绩值时,先从match文件中提取匹配项:
m=$(grep $i match)
然后通过m唯一定位“当前记录”来提取“成绩”:
x=$(grep “$m” 5、完整的脚本(为便于讨论,加注了行号)
01:j=$(grep -c ' ' score)
02:cut -d ' ' -f1,2match
03:max=0
04:for((i=1;i<=$j;i=i+1))
05:do
06:m=$(grep $i match)
07:x=$(grep –m 1 “$m” 08:if [ $max -lt $x ]
09:then max=$x
10:fi
11:done
12:echo “The highest of the score is:$max”
6、设计评价
该程序的设计初衷就是通过接近真实问题的解决,让学生有效地掌握Linux命令,从这点看,本例达到了目的,因为程序中用到了教材中要求掌握的几乎所有命令(详见3.2)。另外,过滤器和管道命令是Linux Shell编程的特色,本例通过数据库编程中不可回避的记录定位问题,充分展示了如何巧用过滤器和管道命令。还有一点,因为本例应用于教学,所以对于学生的接受程度作了充分考虑,实践证明效果良好,教师可通过一节课深入剖析设计思路和程序语法,在学生完全理解解题思路与实现后,在第二节课可以将程序设计引向深入,比如,可让学生考虑一下实现:
(1)能否实现同时显示最高分的学生学号、姓名和成绩?
(2)在(1)的基础上,能否实现并列第一的多个学生的信息显示?
由于这两个问题的实现并不十分困难,这里就不再展开讨论了。当然,也正是出于初衷,本例的数据库结构设计贴近Linux Shell编程需要,而没有顾及实际数据库设计的原则,要求“学号必须严格按+1连续递增”,这个问题的根本解决需要对“学号”字段进行设计,这已超出了本文的讨论范围。
四、总结
通过编写Shell程序来掌握命令,关键是构造好的教学用例,好的教学用例应该能够涵盖学生所学的知识,提高学习兴趣,有利于学生对所学知识的掌握。这就要求任课教师必须充分理解教材中每一条命令,包括其中的每一个选项及参数的用法,同时要有宽广的知识面,唯有如此,才能设计出在学生接纳程度之内,帮助学生有效掌握Linux命令的适用程序。
注释:
①如果系统设置为自动启动图形系统,那么可以通过运行终端仿真程序,进入Shell,在命令提示符后面输入任何命令及参数。
②不同的是,在DOS中,command.com只有一个,而在Linux下比较流行的Shell有好几个,每个Shell都各有千秋。一般的Linux系统都将bash作为默认的Shell。
参考文献:
[1]信息产业部全国电子信息应用教育中心.Linux系统及网络理论与实践教程[M].中国建材工业出版社,2004.5
关键词:Linux Shell 命令行 Shell编程
中图分类号:G434文献标识码:A 文章编号: 1673-1875(2009)03-105-02
一、问题的提出
在GNIIT课程中有关的Linux学习单元,其主要目的就是使学生了解Linux Shell,以便能够理解并实现模块中的项目所要求的远程连接到服务器进行用户权限管理,因此该单元涉及到大量的在Linux下进行系统管理的命令,使用命令行进行管理是Linux系统的特点,但这对于习惯了Windows的学生来说,是比较难适应的,原因有二,一是它改变了只需点击鼠标即可完成复杂功能的操作习惯,二是命令行方式下每条命令及其选项、参数的记忆确实让人头疼。因此找到一个能提高学生学习兴趣和学习效果的方法就显得非常重要。
孤立地学习和记忆每一条命令经常会令学生前学后忘,无法把所学的命令融会贯通,以致产生厌学、弃学的思想。针对于此,如果能够设计出一个解决基于实际问题的算法,编写出程序,把前后所学的命令串联起来,无疑会提高学生对所学命令的掌握,同时这也是GNIIT教学一直倡导的“学以致用”。
实现上述想法,可以利用Linux Shell编程。
二、相关知识
用户登录进入Linux系统时,可以进入基于X Window的图形视窗系统GDE完成很多工作,但是在服务器应用环境下的很多情况需要远程连接到服务器进行管理配置,而且使用命令行模式进行管理更加方便和简单,因此学习Linux,Shell的学习和使用是必不可少的一部分。
如果系统设置为不自动启动图形接口,那么用户登录时,实际进入了Shell①。Shell是什么呢?确切一点说,Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。
当用户使用Linux时是通过命令来完成所需工作的。一个命令就是用户和Shell之间对话的一个基本单位,它是由多个字符组成并以换行结束的字串。Shell解释用户输入的命令,就像DOS里的command.com一样②。
作为命令语言互动式地解释和执行用户输入的命令只是Shell功能的一个方面,Shell还可以用来进行程序设计,它提供了定义变量和参数的手段以及丰富的程序控制结构。使用Shell编程类似于DOS中的批处理文件,称为Shell script,又叫Shell程序或Shell命令文件。
三、一个Shell编程实例
Shell程序的设计,应该尽可能多地应用所学命令,同时还要兼顾学生的接受程度。来看下面这个问题。
1、问题
已将某班级学生某门课程考试成绩存储在score文件中。该文件的示例数据如下:
01 ZHANG 82
02 WANG 91
03 LI 76
......
在此文件中,字段定界符是‘ ’(空格)。不同的字段是学号,姓名,成绩。要求编写一个shell脚本,能够显示出成绩最高的学生的学号、姓名和成绩。例如:
The highest of the score is 91
2、题目设计目标
编写一个Shell程序解决这个问题,需要运用到以下命令:
1)vi编辑器创建和编辑文档;
2)创建和执行脚本;
3)标准输入与输出以及重定向;
4)grep和cut过滤器的特性和选项;
5)用管道结合多个命令;
6)创建变量;
7)计算表达式;
8)使用if构造执行基于条件的shell脚本;
9)用于执行重复任务的构造(while、for或until构造);
10)使用echo命令显示消息。
以上部分几乎涵盖了教材中所介绍的全部命令。当然,有些部分,比如上面所列的“创建变量”和“计算表达式”有多种方法和命令形式,取决于个人的喜好,同样,对于用于执行重复任务的构造(while、for或until构造),也由编写习惯决定。
3、问题分析
这是一个典型的求最大值/最小值问题。对于已经学习过1-2门程序设计语言课程的学生来说,不难理解如下算法:
结果变量y赋初值;
循环体
x=当前记录值
分支结构(x和y比较)
y中的值即所求结果
对于该算法,需要解决的问题包括:
1)初值。求最大值问题时,赋给变量y的初值为问题解域中的最小值。对于该题,问题解的集合为[0,100],因此初值赋为0。
2)循环体。这里采用for构造。Shell程序中for语句的用法为for(表达式1; 表达式2; 表达式3)
表达式1:起始比较位置。i=1
表达式2:循环结束判断。i≤记录数,而记录数可由表达式
j=$(grep -c ' ' score)
求得,因此表达式2即可写成
i<=$j
表达式3:增量。i=i+1
3)分支结构。对于求最大值问题,
if 当前记录值>y
then y=当前记录值
fi
4、该题的难点——如何定位“当前记录”
本题“数据库”中的“字段”分别是学号(“数字”)、姓名(“字母串”)和成绩(“数字”)。如果在典型的关系数据库系统中只需要把该“数据表”中的“学号”作为关键字即可定位记录,但是Shell命令中没有直接用于定位当前记录的命令,只能使用过滤器(通常是用管道结合多个过滤器命令)来找出每个记录区别于其他记录的个体特征,即“关键字段”。而使用过滤器命令不能只把学号作为“关键字段”。试考虑如下记录段
01 ZHANG 82
02 WANG 91
03 LI 76
用grep “1”是无法区分出数据库中的第1和第2条记录的。这时可以采取把“学号+姓名”作为关键字的办法,具体做法是通过cut命令过滤出score文件中的第一和第二列,存放到另一个文件match中。
cut -d ' ' -f1,2
此时,match文件的内容为:
01 ZHANG
02 WANG
03 LI
在循环体中,当每次取欲比较的成绩值时,先从match文件中提取匹配项:
m=$(grep $i match)
然后通过m唯一定位“当前记录”来提取“成绩”:
x=$(grep “$m”
01:j=$(grep -c ' ' score)
02:cut -d ' ' -f1,2
03:max=0
04:for((i=1;i<=$j;i=i+1))
05:do
06:m=$(grep $i match)
07:x=$(grep –m 1 “$m”
09:then max=$x
10:fi
11:done
12:echo “The highest of the score is:$max”
6、设计评价
该程序的设计初衷就是通过接近真实问题的解决,让学生有效地掌握Linux命令,从这点看,本例达到了目的,因为程序中用到了教材中要求掌握的几乎所有命令(详见3.2)。另外,过滤器和管道命令是Linux Shell编程的特色,本例通过数据库编程中不可回避的记录定位问题,充分展示了如何巧用过滤器和管道命令。还有一点,因为本例应用于教学,所以对于学生的接受程度作了充分考虑,实践证明效果良好,教师可通过一节课深入剖析设计思路和程序语法,在学生完全理解解题思路与实现后,在第二节课可以将程序设计引向深入,比如,可让学生考虑一下实现:
(1)能否实现同时显示最高分的学生学号、姓名和成绩?
(2)在(1)的基础上,能否实现并列第一的多个学生的信息显示?
由于这两个问题的实现并不十分困难,这里就不再展开讨论了。当然,也正是出于初衷,本例的数据库结构设计贴近Linux Shell编程需要,而没有顾及实际数据库设计的原则,要求“学号必须严格按+1连续递增”,这个问题的根本解决需要对“学号”字段进行设计,这已超出了本文的讨论范围。
四、总结
通过编写Shell程序来掌握命令,关键是构造好的教学用例,好的教学用例应该能够涵盖学生所学的知识,提高学习兴趣,有利于学生对所学知识的掌握。这就要求任课教师必须充分理解教材中每一条命令,包括其中的每一个选项及参数的用法,同时要有宽广的知识面,唯有如此,才能设计出在学生接纳程度之内,帮助学生有效掌握Linux命令的适用程序。
注释:
①如果系统设置为自动启动图形系统,那么可以通过运行终端仿真程序,进入Shell,在命令提示符后面输入任何命令及参数。
②不同的是,在DOS中,command.com只有一个,而在Linux下比较流行的Shell有好几个,每个Shell都各有千秋。一般的Linux系统都将bash作为默认的Shell。
参考文献:
[1]信息产业部全国电子信息应用教育中心.Linux系统及网络理论与实践教程[M].中国建材工业出版社,2004.5