实验任务1
运行/notebooks/workspace中的Shell脚本example.bash
执行Shell脚本的方法有两种:一是将Shell脚本文件设置为可执行,直接执行该文件;二是指明使用bash解释、执行Shell脚本文件。
对一个Shell脚本文件,设置该文件为可执行后,在Shell下键入:
路径/文件名.bash
就可以执行该Shell脚本文件,因此,如果当前工作目录中包含该文件,则使用命令“./文件名.bash”,其中“./”为当前工作目录。
对Shell脚本程序进行调试,使用第二种执行方式:bash 路径/文件名.bash
就可以执行该Shell脚本文件。
实验任务2
请使用一个命令行一次执行ls, pwd, whoami三个命令。
shell允许同一命令行输入多个命令运行,但是中间要用分号隔开.
实验任务3
创建和执行一个脚本文件test1,该脚本文件执行ls, pwd, whoami三个命令。
先用touch 创建文件,再用vi编辑文件,文件中#开头的一行是注释,第一行#!称为魔数,用它来指示哪个shell要解释本脚本文件。再使用bash 路径/文件名执行文件。
实验任务4
获取当前用户的默认主目录路径。(提示:存放主目录路径的环境变量)
bash shell使用环境变量来存储有关shell会话和工作环境的信息。这些信息包括系统的名称,登录到系统上的用户的名称,用户的默认主目录,shell查找程序的搜索路径等。
1、使用set命令可以显示全部环境变量。其中“HOME=”的那一行就是用户主目录。
2、使用“$变量名”的方式可以获取环境变量的值,如 echo $HOME
实验任务5
试统计一下example1的行数、词数和字节数。
wc命令提供了对数据中文本的技术,默认情况下,它会输出文本的行数、词数、字节数。如下图所示,example1文件有行数为4,词数为11,字节数为71.
实验任务6
请使用管道,将dpkg -l命令显示的安装包的列表中vim相关的包过滤出来。(提示:grep命令用于过滤字符串,详见本次实验7.4)
管道用作将一个命令的输出重定向到另外一个命令中,管道符“|”将两个命令隔开,它的作用是将dpkg -l的输出作为grep vim命令的输入。grep vim命令用于过滤与vim有关的文件。
实验任务7
使用bash计算(1+5)*19
使用的方法是使用方括号或双括号,用于将数学运算的结果赋值给某个变量。先把括号里的(1+5)赋值给var1,再把var1 *19 的值赋给var2,用echo命令显示结果。
实验任务8
写一个bash脚本文件,功能为:提示输入一个用户名,判断该名字是否是当前操作者。(提示:输入用户名可使用read命令,可使用whoami命令获取当前操作者)
先用touch命令创建文件,再用vi命令编辑文件,使用case命令来实现多条件结构。命令行为:
case 字符串 in
模式)
语句
;;
模式2|模式3)
语句
;;
*)
默认执行的语句
;;
esac
因为使用case 命令时出错,以为是case命令使用不正确,就又使用if 命令来使用多条件结构
在写如上图的if [ $name = $whoami ]时,”[“和”]”与参数之间,以及参数与值之间,都有空格分割。'='用于判断字符串是否相等,whoami=`whoami`是将whoami命令的输出值赋给变量whoami,我就是因为这个原因才导致出错。
实验任务9
写一个shell脚本,检查/notebooks/目录下的每个文件是一般文件还是目录。(提示:可使用for循环如:“for file in /notebooks/*”来列举/notebooks/目录下的文件)
使用for命令来实现shell 的循环结构,for命令的格式为:
for 变量 in 值表 do 命令表 done
用if 来实现条件结构,-f 判断是否为文件。-d判断是否是目录。
if命令的语法为:if 测试命令 then 命令1 else 命令2 fi
或: if 测试命令 then 命令1 elif 测试命令 then 命令2 fi
实验任务10
请编写脚本,读入学号,输出学生成绩单中该学号对应的学生成绩(包括表的标题,表的名称),如:
图6-8 任务11-步骤1
图6-9 任务11-步骤2
成绩单文件为/notebooks/workspace/data.txt,内容为:
cat /notebooks/workspace/data.txt
课程总成绩学号 姓名 班级 实验课 平时成绩 期末考试 总成绩20111001 白xx 信安1101 0.0 0.0 0 020111002 杜xx 信安1101 0.0 0.0 0 020111003 范xx 信安1101 0.0 0.0 0 0
yongy
实验任务11
通过HOME变量输出用户名有多少个字符?(提示:使用参数置换变量)
${#param}是以参数值的长度作为值;${param##word}是从param的第一个字符开始,删除满足word条件的最长的部分,作为值。
实验任务12
分析下面给出的Shell程序的功能,并运行、调试该程序。
#!/bin/bashIS_someone=`who | grep $1`while [ -z "$IS_someone" ]dosleep 3IS_someone=`who | grep $1`doneecho "watch it,$1 is online!" | wall
#!/bin/bash#开头的一行是注释,#!称为魔数,用它来指示哪个shell要解释本脚本文件。IS_someone=`who | grep $1`
who 命令用来显示关于当前在本地系统上的所有用户信息;
grep $1是过滤有关于$1的内容;“|”将who 命令的输出作为grep $1命令的输入;`` 实现把一个命令的标准输出插在命令行的任何位置。整行命令的含义是将`who | grep $1`的值赋给IS_someone
3. [ -z "$IS_someone" ] 为while循环的测试条件,-z为判断后面的字符串是否为0,为0测试条件为真。
5. sleep 3
sleep命令可以用来将目前动作延迟一段时间,这里是3s。
3、4、7行为while循环结构.
8.echo "watch it,$1 is online!" | wall
wall命令用于向系统当前所有打开的终端上输出信息。通过wall命令可将信息发送给每位同意接收公众信息的终端机用户,若不给予其信息内容,则wall命令会从标准输入设备读取数据,然后再把所得到的数据传送给所有终端机用户。
“watch it, $1 is online!”作为wall命令的输入,通过wall命令发送给每位同意接收公众信息的终端机用户。
这个shell程序用来监控用户是否登录,一旦登录会向系统用户广播其上线了。
运行结果:
调试:用户未登录,IS_someone就为空,故程序一直循环执行。
选项-x的意思为在变量替换之后但执行之前,显示命令文件的每一行。
由于使用了-x选项,该结果中包含了调试信息,即结果中以加号(+)开头的行,表示shell对该行命令的解释,比如grep $1被换成了grep root,将变量进行了替换再执行;没有以加号(+)开头的行则表示输出的信息。
2. 思考题回答
1、Shell脚本中的程序段有错误,但该程序段在运行中没有被执行,问该错误能否被表现出来?
如果是语法错误能被表现出来
如果是逻辑错误且运行中未被执行则不会被表现出来。
2、总结Shell脚本查错的基本方法和过程。
shell程序执行后会自动检测语法错误,并显示第几行出错,可手动更改。
如果是逻辑错误需要自己调试。
调试需要使用bash的选项:
-x在变量替换之后但执行之前,显示命令文件的每一行。
-v在执行之前显示命令文件的每一行,就像在命令行输入一样。
-n解释但不执行命令。
+x关闭追踪。
3. 实验体会
本次实验跟着指导书一步步走完,因为指导书很详细,每出现什么错误,但是收获很大。知道了怎么执行shell程序,可以使用命令“路径/文件名.bash”或“bash 路径/文件名.bash”。知道了同一命令行可以输入多个命令运行,但是中间要用分号隔开。编辑shell文件时应注意第一行,如“#!/bin/bash”第一行#!称为魔数,用它来指示哪个shell要解释本脚本文件。知道了使用“$变量名”的方式可以获取环境变量的值,如 echo $HOME。知道了wc命令提供了对数据中文本的技术,默认情况下,它会输出文本的行数、词数、字节数。知道了管道用作将一个命令的输出重定向到另外一个命令中,管道符“|”将两个命令隔开,管道符“|”左边的命令输出会作为右边命令的输入。掌握了for循环结构和if的条件结构,使用for命令来实现shell 的循环结构,for命令的格式为:
for 变量 in 值表 do 命令表 done
用if 来实现条件结构,-f 判断是否为文件。-d判断是否是目录。
if命令的语法为:if 测试命令 then 命令1 else 命令2 fi
或: if 测试命令 then 命令1 elif 测试命令 then 命令2 fi。
用read命令可以读取输入的内容,用grep命令可以过滤相关信息。
了解了参数置换变量,如${#param}是以参数值的长度作为值;${param##word}是从param的第一个字符开始,删除满足word条件的最长的部分作为值。