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阅读器的搜索功能,哭了)

image-20230307101225964

我用了"此外",那部分的方法。这种方法的格式举例(举个例直接就明白了):

# 三个数字对应的位置分别代表 拥有者 群组 其他人,这三个群体,数字大小为分别给他们的权限
# 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而忽略了那部分。

posted @ 2023-03-07 10:46  buaa_nr  阅读(1448)  评论(1)    收藏  举报