1.基本信息
- 实验课程:Linux 程序设计
- 设课形式:非独立
- 课程学分:2
- 实验项目:Shell 程序设计
- 项目类型:验证
- 项目学时:2
2.实验预习
实验目的和要求:
理解 Shell 程序的设计方法;
熟悉 Shell 程序的编辑、运行、调试方法与过程。
实验条件:
装有 Linux 操作系统的微型计算机;
实验方法:
Shell 程序的编辑可使用 vi,emacs 等 Linux 下的各种文本编辑器。本课程实验可使用 Ubuntu 下的 gedit 。
Shell 程序的执行有两种方式:bash [Shell 程序名] 或 ./ [Shell程序名]
- Shell 程序名称为 test.sh,则可以通过 bash test.sh或./test.sh。 但是要注意在使用./ [Shell 程序名]时必须确保对 Shell 程序具有可执行 权限。
Shell 程序的调试可以通过建立多个工作区交互进行。
3.实验过程
3.1 简单 SHELL 实验
(请在 vi 中逐一编辑并执行以下 6 个 shell 脚本程序)
3.1.1 编写一个简单的回显用户名的 shell 程序
#!/bin/bash
#filename:dat
echo "Welcome to my world,Mr.$USER:"
echo "Now is:$(date)"
3.1.2 使用if-then 语句创建简单的shell 程序
#!/bin/bash
#filename:bbbb
echo -n "Do you want to break: Y or N"
echo
read ANSWER
if [ $ANSWER = Y ]
then
echo "success exit"
exit
fi
3.1.3 使用if-then-else 语句创建一个根据输入的分数判断是否及格的 shell 程序
#!/bin/bash
#filename:ak
echo -n "please insert a score:"
read SCORE
echo "you score is $SCORE"
if [ $SCORE -ge 60 ]; then
echo "congratulation"
else
echo "I’m sorry you don’t pass the exam"
fi
3.1.4 使用 for 语句创建简单的 shell 程序
#!/bin/bash
#filename:mm
for x in 1 2 3 4
do
echo $x
done
3.1.5 使用while 语句创建一个计算 1-5 的平方的 shell 程序。
#!/bin/bash
int=0
while [ $int -le 5 ]
do
sq=`expr $int \* $int` #记住是上波浪号
echo $sq
int=`expr $int + 1`
done
echo "final"
3.1.6 使用 while 语句创建一个根据输入的数值求累加和(1+2+3+4+…+n)的 shell 程序
#!/bin/bash
#filename:sum
echo -n "Please Input Number:"
read NUM
number=0
sum=0
while [ $number -le $NUM ]
do
echo "number:$number sum:$sum"
number=`expr $number + 1 `
sum=` expr $sum + $number `
done
3.2 较复杂 SHELL 实验
考勤模拟Shell 程序设计,用shell 设计一个模拟考勤程序,实现如下功能选择界面:
1:上班签到
2:下班签出
3:缺勤信息查阅
考勤程序运行后,提示用户输入上述功能选择,并验证用户输入的用户名和密码;用户信息保存在 userinfo.dat 中。
如果是上班签到,记录签到信息,如果签到时间大于上午 8 时,则提示用户迟到,并记录该迟到信息到 check.dat 中。
如果是下班签出,记录签出信息,如果签出时间小于下午 6 时,则提示用户早退,并记录该早退信息到 check.dat。
如果用户选择确信信息查询,则将 check.dat 中对应的用户迟到早退的信息查询出来并显示。用户选择功能执行完,Shell 程序继续回到功能选择界面等待下一个用户进行操作。
3.3 思考题
3.3.1 编写一个 shell 脚本,它带一个命令行参数,这个参数是一个文件。如果这个文件是一个普通文件,则打印文件所有者的名字和最后的修改日期。如果程序带有多个参数,则输出出错信息。
#!/bin/bash
if [ $# -eq 1 ]
then
if [ -f $1 ]
then
echo "The owner of the file $1 is $(stat -c %U $1)" q
echo "The last modification date of the file $1 is $(stat -c %y $1)"
else
echo "$1 is not a regular file"
fi
else
echo "Wrong number of arguments"
fi
3.3.2 编写一个 bash 脚本程序,用 for 循环实现将当前目录下的所有.c 文件移到指定的目录下,最后在显示器上显示指定目录下的文件和目录。
#!/bin/bash
# 检查参数个数是否等于1
if [ $# -eq 1 ]
then
# 检查参数是否是一个有效的目录
if [ -d $1 ]
then
# 遍历当前目录下的所有.c文件
for file in *.c
do
# 将文件移动到指定的目录
mv $file $1
done
# 打印一条消息表示操作完成
echo "所有.c文件已经移动到$1"
# 列出指定目录下的文件和目录
ls -l $1
else
# 如果参数不是一个有效的目录,打印一条错误消息
echo "$1不是一个有效的目录"
fi
else
# 如果参数个数不等于1,打印一条错误消息
echo "参数个数错误"
fi
3.3.3 编写一个名为 dirname 的脚本程序,它将参数作为一个路径名,并将该路径前缀(不包含最后部分的整个串)写到标准输出 。
#!/bin/bash
# 检查参数个数是否等于1
if [ $# -eq 1 ]
then
# 使用dirname命令获取参数的路径前缀
prefix=$(dirname $1)
# 将路径前缀打印到标准输出
echo $prefix
else
# 如果参数个数不等于1,打印一条错误消息
echo "参数个数错误"
fi
3.3.4 编写一个累加器脚本程序,用 Fiboracci 数列的前 10 个数做参数。
#!/bin/bash
# 定义一个变量sum,用来存储累加和,初始值为0
sum=0
# 遍历所有的参数
for num in $@
do
# 将参数转换为整数,并加到sum上
sum=$((sum + num))
done
# 打印累加和
echo "The sum is $sum"
3.3.5 写一个 shell 脚本,包含两个数字数组 array1 和 array2,分别初始化为{1,2,3,4, 5}和{1,4,9,16,25}。脚本生成并显示一个数组,其中的元素是这两个数组中 对应元素的和,数组中第一个元素是 1+1=2,第 2 个元素是 2+4=6 等。
#!/bin/bash
# 定义并初始化两个数字数组array1和array2
array1=(1 2 3 4 5)
array2=(1 4 9 16 25)
# 定义一个空数组sum_array,用来存储元素之和
sum_array=()
# 获取数组的长度
length=${#array1[@]}
# 遍历数组的索引
for i in $(seq 0 $((length - 1)))
do
# 计算两个数组中对应元素的和,并追加到sum_array中
sum=$((array1[i] + array2[i]))
sum_array+=($sum)
done
# 打印sum_array的内容
echo "The sum array is ${sum_array[@]}"
3.3.6 某工厂产管理员 hnsd 负责统计各车间产品数据,计算机安装双硬盘保证数据安全。该管理员每天上午 12:00 和下午 17:30 必须对数据进行双硬盘备份,需要备份的数据存放于/home/hnsd/workdata/目录,备份数据别存放于/home/hnsd/disk1backup/(第一块硬盘) 和/dev/disk2backup/ (第二块硬盘)目录, 且文件名形式为yyyymmdd_workdata1.tar.gz(上午备份文件)和 yyyymmdd_workdata2.tar.gz(下午备份文件)其 yyyy、mm、dd 年月日。
- 设计 shell 程序实现该任务
- 编写 crontab 文件实现述任务自调度
可执行脚本:
#!/bin/bash
#获取当前日期
date=$(date +%Y%m%d)
#获取当前时间
time=$(date +%H:%M)
#判断是上午还是下午
if [ "$time" \< "12:00" ]; then
suffix=workdata1.tar.gz #上午备份文件后缀
else
suffix=workdata2.tar.gz #下午备份文件后缀
fi
#生成备份文件名
filename=$date"_"$suffix
#压缩数据目录为tar.gz格式
tar -czvf $filename /home/hnsd/workdata/
#复制备份文件到第一块硬盘的备份目录
cp $filename /home/hnsd/disk1backup/
#复制备份文件到第二块硬盘的备份目录(假设已经挂载)
cp $filename /dev/disk2backup/
将这个脚本文件赋予可执行权限:
chmod +x backup.sh
编辑crontab文件来实现定时任务自调度。
0 12 * * * /path/to/backup.sh #上午12:00执行脚本(替换为实际路径)
30 17 * * * /path/to/backup.sh #下午17:30执行脚本(替换为实际路径)
4.实验心得
在实验过程中,我也遇到了一些困难和挑战,比如Linux的环境配置、命令行界面的使用、权限管理等。为了克服这些困难,我们需要有足够的耐心和毅力,不断地查阅资料、询问老师或同学、尝试不同的方法。通过这样的努力,我们逐渐熟悉了Linux的特点和规则,并且发现了Linux的魅力和乐趣。