BUAA_2023_os_lab0上机总结
本次上机给了两个题目:exam/extra 其中exam占5分,extra为附加题,仅占一分。
exam
题目没有记,不过题目工整,代码划分地也比较整齐,直接贴代码来解释了。本题一共两问,第一问为makefile编写,第二问为shell编写。
Makefile
.PHONY: clean
all: test.c # make默认执行
gcc test.c -o test
run:
./test
clean:
rm -f test
如上所示,题目在lab0-exam分支下给了一个空的Makefile文件,让我们自行实现:
1.执行make可以编译同目录下的test.c文件,生成可执行文件。
单单执行make而不加任何标签的话,默认执行makefile中的第一个目标,因此我们把编译test.c的目标放在最上面。目标随便起个名叫all,编译出可执行文件依赖于test.c,第二行的编译命令就很简单了。
2.执行make run可以运行test可执行文件。
这个直接构建一个叫run的目标,执行这个文件不需要任何依赖,直接写执行命令即可。
3.执行make clean可以清除当前目录下的test可执行文件。
构建一个叫clean的目标,也不需要依赖。
Shell
这一问一共有工工整整并列的8个需求。我在代码中用 # 序号 题目描述的格式来表示题号以及题干,在代码下面会着重解释一些恶心到我的点。
#!/bin/bash
mkdir mydir
# 1 在shell的目录下创建一个叫mydir的目录
# chmod a +xwr mydir
chmod 777 mydir # 不明白的话,看一下代码后的说明就明白了
# 2 将上面的mydir目录的权限设置为"所有用户" "可读可写可执行"。
touch myfile
echo "2023" >> myfile # 创建后用echo将2023从标准输出重定向到新建的文件中即可。这句话双引号加不加都可以。
# 3 在shell的目录下创建一个叫myfile的文件,并将这个文件的内容设置为"2023"(内容中不含双引号)。
mv moveme mydir/
# 4 将shell目录下的moveme文件移动到刚刚新建的目录mydir下
cp copyme mydir/copied # 直接把copied打在命令里即可,会自动新建这个名字的文件
# 5 将shell目录下的copyme文件移动到mydir目录下同时命名为copied
cat readme
# 6 将shell目录下readme的内容输出到标准输出
gcc bad.c 2> err.txt # > 重定向不加数字,默认数字为1(即,1>),也即标准输出,现在要针对标准错误,他对应的数字是2,因此要用2>
# 7 编译shell目录下的bad.c文件并将标准错误信息输出到err.txt中
x=1
n=10 # 参数默认为10
if (( $# == 1 )) # 如果传参的话再修改默认参数的值,$# 表示传入参数的个数
then
let n=$1 # 用参数值取代默认的10
fi
mkdir gen # 创建gen目录
chmod +x gen # 这个应该没有啥用吧
i=1
let n=n+1 # 这是为了让循环能循环n次的同时,循环变量i从下标1开始,就可以直接 $1.txt 命名了
cd gen # 要进入gen目录
while(($i < $n)) # 循环n次
do
touch $i.txt
let i=i+1 # 别忘了循环变量要加1
done
# 8 没有提供这个参数的情况??? 如果在执行这个shell文件的时候传进了一个参数,那么数量(接着往后读就理解了)为这个参数值,如果没有传参,那么数量就默认为10。"数量",指要求自己新建一个gen目录,并在里面新建这个"数量"多少的文件,分别命名为1.txt 2.txt ...比如,“数量”为3,则在gen目录下新建1.txt 2.txt 3.txt这3个文件.
2:修改权限
修改权限这个当初不会,然后去找指导书找了有一会儿的时间找到了(我不知道ctrl+F可以直接打开pdf阅读器的搜索功能,哭了)
我用了"此外",那部分的方法。这种方法的格式举例(举个例直接就明白了):
# 三个数字对应的位置分别代表 拥有者 群组 其他人,这三个群体,数字大小为分别给他们的权限
# r=4读权限,w=2写权限,x=1执行权限,给哪些权限就把哪些数字加起来,比如,5 = 4 + 1就是给某个群体读和执行权限
chmod 777 test1 # 7 = 4 + 2 + 1 因此本命令给了三个群体(也就是所有用户)所有权限
chmod 124 test2 # 1->给了 拥有者 执行权限 2->给了 群组 写权限 3->给了 其他人 读权限
8.
当时我把then 直接写在if 的同一行了,然后本地执行shell就一直说then附件有语法错误,后来整了半天,把then按照教程放到下一行就好了。后来我查了查,应该是if 和 then 之间需要有一个 换行 或者 分号 分隔 ,也就是说是可以放在同一行的(因为我见过这么写),但是要注意加上分号!,即if condition; then
extra
这个一共四问,最后一问坐牢了,丢了25分,不过由于附加题只有1分,因此也就是0.25分,所以也没太在意。
这道题是给了框架的,只需要补全出现 # Your code here. 的地方。
#!/bin/bash
if [ $# -eq 1 ]; # 无参数
then
# Your code here. (1/4)
grep -E "WARN|ERROR" $1 > bug.txt # 题目提示使用-E可以开启grep的正则表达式模式
else
case $2 in
"--latest")
# Your code here. (2/4)
tail -n 5 $1 # 题目提示查找tail的用法
;;
"--find") # haiyou yige canshu
# Your code here. (3/4)
grep $3 $1 >> $3.txt
;;
"--diff") # haiyouyigecanshu
# Your code here. (4/4)
if diff $1 $3 > /dev/null # 题目提示如果想屏蔽一个命令的输出的话可以将输出重定向到 /dev/null
then
echo "same"
else
echo "different"
fi
;;
esac
fi
有以下四种传参情况,题目分的挺开的,给的框架也比较清晰。
调用格式:shell.sh文件1路径 (参数1 参数2...)
(下表中的"参数个数"不包括一定有的 文件1路径)
| 参数个数 | 参数描述 | 行为 |
|---|---|---|
| 0 | 无 | 把文件1包含WARN ERROR字符串的行输出到bug.txt 文件中 |
| 1 | --latest | 输出文件1的后五行(不足5行则全部输出) |
| 2 | --find 字符串 | 忘了,但是通过代码看应该是说把文件1中含有参数字符串的行输出到以这个字符串.txt为名字的文件中 |
| 2 | --diff 文件2路径 | 对比文件1、2的内容,相同的话输出same,不同的话输出different |
具体实现可以看代码以及注释。
第四问坐牢了,想了半天没想明白怎么把diff的判断结果转化成一个数字,然而其实根本不用什么手动转换。当时没明白if 之后本质是个命令,,而每个命令都是有一个返回值的,用man diff命令可以查到diff命令的返回值
总结
主要就是语法,没有任何思维难度,不过要注意不要敲错文件名。开卷考试,所有语法点都不用查就会的话可能半个多小时就能全部搞定了(像我就是有的还得查所以没那么快)。可能是经过了计组的拷打,这上机也没有一点紧张的,但是最终因为diff坐牢了, 延长了20min还是坐牢了。此外不知道ctrl+F可以打开pdf的查找功能,这实在太xx了,《如果知道的话最后那一小问肯定也能做对》.....不然的话指导书上是有diff(或者说shell里面的if条件本质是一条命令)这个点的,只是想着找diff而忽略了那部分。

浙公网安备 33010602011771号