Lab0 实验报告
BUAA 2023 Operating System Lab0
(一)思考题
Thinking 0.1
思考下列有关 Git 的问题:
• 在/home/21xxxxxx/learnGit(已初始化)目录下创建一个名为 README.txt 的文件。执行命令 git status > Untracked.txt。
• 在 README.txt 文件中添加任意文件内容,然后使用 add 命令,再执行命令 git status > Stage.txt。
• 提交 README.txt,并在提交说明里写入自己的学号。
• 执行命令 cat Untracked.txt 和 cat Stage.txt,对比两次运行的结果,体会README.txt 两次所处位置的不同。
Untracked.txt 里没有尚未暂存以便提交的文件,有Untracked.txt和README.txt两个未跟踪文件。Stage.txt里有尚未暂存以便提交的文件README.txt,有Stage.txt和Untracked.txt两个为跟踪的文件。
• 修改 README.txt 文件,再执行命令 git status > Modified.txt。
• 执行命令 cat Modified.txt,观察其结果和第一次执行 add 命令之前的 status 是否一样,并思考原因。
与一开始相比,会在尚未暂存以便提交的文件地方显示“修改:README.txt”,是因为README.txt已经被跟踪,刚才被修改还尚未加入暂存区。
Thinking 0.2
仔细看看0.10,思考一下箭头中的 add the file 、stage the file 和 commit 分别对应的是 Git 里的哪些命令呢?
add the file对应着**git add <file>**命令,将未追踪文件添加追踪并且添加到暂存区。
stage the file对应着**git add<file>**命令,将修改的文件添加到暂存区。
commit对应着git commit命令,将暂存区的文件提交到git仓库中。
Thinking 0.3
-
代码文件 print.c 被错误删除时,应当使用什么命令将其恢复?
使用
git restore print.c
-
代码文件 print.c 被错误删除后,执行了 git rm print.c 命令,此时应当使用什么命令将其恢复?
使用
git reset HEAD print.c&&git checkout -- print.c
或者
git restore --staged print.c&&git restore -- print.c
-
无关文件 hello.txt 已经被添加到暂存区时,如何在不删除此文件的前提下将其移出暂存区?
使用git restore --staged hello.txt
或者git rm --cached hello.txt
Thinking 0.4
思考下列有关 Git 的问题:
• 找到在/home/21xxxxxx/learnGit 下刚刚创建的 README.txt 文件,若不存 在则新建该文件。
• 在文件里加入 Testing 1,git add,git commit,提交说明记为 1。
• 模仿上述做法,把 1 分别改为 2 和 3,再提交两次。
• 使用 git log 命令查看提交日志,看是否已经有三次提交,记下提交说明为 3 的哈希值a。
• 进行版本回退。执行命令 git reset –hard HEAD^后,再执行 git log,观察其变化。
此时对应的是commit2的hash值,使用git log后,commit 3的提交消失了。
• 找到提交说明为 1 的哈希值,执行命令 git reset –hard <hash> 后,再执 行 git log,观察其变化。
此时2,3的提交消失了,此时对应的是commit1的状态
• 现在已经回到了旧版本,为了再次回到新版本,执行 git reset –hard <hash> ,再执行 git log,观察其变化。
此时1,2,3次的提交记录都恢复了。
Thinking 0.5
执行如下命令, 并查看结果
• echo first
• echo second > output.txt
• echo third > output.txt
• echo forth >> output.txt
执行结果依次为:
- 在终端上输出字符串”first”
- 终端上无输出,output.txt文件中有”secend”
- 终端上无输出,output.txt文件被覆盖为”third”
- 终端上无输出,output.txt文件被append字符串”forth”
Thinking 0.6
使用你知道的方法(包括重定向)创建下图内容的文件(文件命名为 test), 将创建该文件的命令序列保存在 command 文件中,并将 test 文件作为批处理文件运行, 将运行结果输出至 result 文件中。给出 command 文件和 result 文件的内容,并对最后的结果进行解释说明(可以从 test 文件的内容入手). 具体实现的过程中思考下列问 题: echo echo Shell Start 与 echo `echo Shell Start`效果是否有区别; echo echo $c>file1 与 echo `echo $c>file1`效果是否有区别.
#command
echo 'echo Shell Start...'>test
echo 'echo set a = 1' >>test
echo 'a=1' >>test
echo 'echo set b = 2'>>test
echo 'b=2'>>test
echo 'echo set c = a+b'>>test
echo 'c=$[$a+$b]'>>test
echo 'echo c=$c'>>test
echo 'echo save c to ./file1'>>test
echo 'echo $c>file1'>>test
echo 'echo save b to ./file2'>>test
echo 'echo $b>file2'>>test
echo 'echo save a to ./file3'>>test
echo 'echo $a>file3'>>test
echo 'echo save file1 file2 file3 to file4'>>test
echo 'cat file1>file4'>>test
echo 'cat file2>>file4'>>test
echo 'cat file3>>file4'>>test
echo 'echo save file4 to ./result'>>test
echo 'cat file4>>result'>>test
#result
3
2
1
在实验过程过程中,echo echo Shell Start会输出echo Shell Start,然而echo `echo Shell Start`会输出Shell Start,它们有输出上的不同。
echo echo $c>file1会在file1文件中写入echo,**echo `echo $c>file1`**没有对文件进行写入。
在解决该问时发现了三个易错点
1.echo的使用
echo和`使用容易引起可能的错误导致错误输出,因此如果想要在echo命令中输出字符串echo,最好使用单引号括起来,这样输出的就是一个整体。
2.$的使用
echo中$有着取变量值的作用,如果想要打印$符号,比如echo $a
得到的就是空的输出,查阅资料可知,是由于没有提前定义变量a,因此要输出$也应使用单引号括起来。
3.重定向符号>>或>的使用
我们可能会将数字重定向输入到文件当中,然而如果输出内容的最后一个字符是数字并且和重定向符号相连,那就会导致输出错误或者没有输出。
echo 122>>test
我们想要把122输入到test文件中,但是2>>表示的是将错误信息输出,因此test文件中将没有结果。修改方式为122加上单引号,或者在>>前加上空格。
(二)难点分析
exercise 0.1
第一个问题的难点在于其中第三小问对于文件内容的提取和处理。
首先要解决的一个问题是参数的传递,需要传入AAA BBB两个字符串,我们可以使用变量var1=$1,var2=$2来接收。
第二个问题是特定行数的内容提取。我们可以使用sed函数的-p选项,提取文件的某一行输出。
其格式为
sed 'Xp' <file> #X is the line number you need
接下来使用重定向,即可输出到目标文件中。
exercise 0.2
第二个问题的难点在于参数的引用,代码基本框架已经给出,我们要使用的只有rm和mv两个指令,对于数字的引用,需要用$表示值的引用。还有一个难点在于数字变量的自增,可以有以下两种方法:
let a=a+1 #注意一定等号要紧挨
#or
a=$(($a+1))
exercise 0.3
第三个问题的难点在于目标的寻找,以及最终格式的提取。
首先我们要解决找到含有int的行并且输出,我们可以使用grep指令,具体格式为:
grep -n $target $file
#$target is the target you want to search
#$file is where you search in
接下来我们要提取输出中的数字,我们可以观察到每一行是由{num:str}组成的,但是我们只需要”:”之前的数字,可以使用awk -F的正则表达式提取,并且将最后结果输出到result文件中,具体格式为:
awk -F '[:]' '{print $1}'> $result
# '[:]' is the spilt symbol
# "print" means print in the Terminal
# $1 is the first item that ':' separated
exercise 0.4
第四个问题的难点在于如何处理编译时需引用外部.h文件和如何在Makefile内部调用外部Makefile。
调用外部.h文件可以使用gcc中的-I选项,将后面跟的目录作为第一个寻找头文件的目录,格式如下:
gcc -I ../include -c main.o main.c
在Makefile内部调用外部Makefile
$(MAKE) target -C $(TARGET_PATH)
#if target is the first make,it can be omitted
#TARGET_PATH is a str for the target make's position
(三)实验体会
通过这次实验我有三个方面的体会:
- 各种指令操作的选项众多,我们不能仅仅拘泥于看教程和search on the Internet,更重要的是我们要学会使用man,去官方说明里寻找最official的说明。
- Linux使用博大精深,要学会按照自己的需求在网上寻求帮助,要善于学,乐于学,才能应对各种需求实现的多样性。
- 对于常见指令要做到反复练习,才能更高效的处理需求。
补档
上完机后发现了几个方面的问题
1.chmod的使用
在man的解释中chmod有开启文件或者目录权限的格式,这次要求对所用用户开始读、写、执行的功能,这一次的格式如下
- a表示对全部用户使用
- r代表读权限
- w代表写权限
- x代表执行权限
在说明文档里有一个正则表达式,a是不用加**+**的,r, w,x的使用要用+连接,可以多个字母并联
#正确结果
chmod a+rwx mydir
#错误示范
chmod +a mydir
chmod a+r,+w,+x mydir
2.指令返回值的调用
$?代表上一条指令的返回值,例如使用了diff指令,之后输出$?即可得到两个文件是否相等的返回值,0为相同,a为不同。
diff file1 file2
echo $?
即可在终端上得到0或者1。
3.sh文件中条件语句
if [ condition ]
while [ condition ]
如上,if和while指令都有一个这样的方括号,有这样两个注意点:
- if/while和方括号之间要有一个空格
- condition,既里面的判断条件也要和方括号的左右都间隔一个空格
由于shell通过空格来区分变量,所以对空格十分敏感,这个地方的空格缺一不可。不然就和我一样寄咯