BUAA-OS-lab0
Lab0实验报告
思考题
Thinking 0.1
思考下列有关 Git 的问题:
• 在前述已初始化的 ~/learnGit 目录下,创建一个名为 README.txt 的文件。 执行命令 git status > Untracked.txt。
• 在 README.txt 文件中添加任意文件内容,然后使用 add 命令,再执行命令 git status > Stage.txt。
• 提交 README.txt,并在提交说明里写入自己的学号。
• 执行命令 cat Untracked.txt 和 cat Stage.txt,对比两次运行的结果,体 会 README.txt 两次所处位置的不同。
• 修改 README.txt 文件,再执行命令 git status > Modified.txt。
• 执行命令 cat Modified.txt,观察其结果和第一次执行 add 命令之前的 status 是否一样,并思考原因。
- 解:
- 执行
git status > Untracked.txt
,表示查询当前README.txt
文件状态,并将其记录在Untracked.txt
文件中;git status > Stage.txt
和git status > Modified.txt
同理。 cat Untracked.txt
后,第二行显示Untracked files:
,说明:在README.txt
新建的时候,其处于为未跟踪状态 (untracked);cat Stage.txt
后,第二行显示Changes to be committed:
,说明:在README.txt
中任意添加内容,接着用 add 命令之后,文件处于暂存状 态(staged);cat Modified.txt
后,第二行显示Changes not staged for commit:
,说明:在修改README.txt
之后,其处于被修改状态(modified)。
- 执行
Thinking 0.2
仔细看看0.10,思考一下箭头中的 add the file 、stage the file 和 commit 分别对应的是 Git 里的哪些命令呢?
- 解:
- add the file :
git add
- stage the file:
git add
- commit:`git commit
- add the file :
Thinking 0.3
思考下列问题:
- 代码文件 print.c 被错误删除时,应当使用什么命令将其恢复?
- 代码文件 print.c 被错误删除后,执行了 git rm print.c 命令,此时应当 使用什么命令将其恢复?
- 无关文件 hello.txt 已经被添加到暂存区时,如何在不删除此文件的前提下 将其移出暂存区?
- 解:
git checkout --print.c
git reset HEAD print.c && git checkout --print.c
git rm --cached print.c
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,观 察其变化。
• 找到提交说明为 1 的哈希值,执行命令 git reset --hard 后,再执 行 git log,观察其变化。
• 现在已经回到了旧版本,为了再次回到新版本,执行 git reset --hard ,再执行 git log,观察其变化。
- 解:
- 第一次
git log
- 第二次
git log
- 第三次
git log
- 第四次
git log
- 第一次
Thinking 0.5
执行如下命令, 并查看结果
• echo first
• echo second > output.txt
• echo third > output.txt
• echo forth >> output.txt
- 解:
Thinking 0.6
使用你知道的方法(包括重定向)创建下图内容的文件(文件命名为 test), 将创建该文件的命令序列保存在 command 文件中,并将 test 文件作为批处理文件运行, 将运行结果输出至 result 文件中。给出 command 文件和 result 文件的内容,并对最 后的结果进行解释说明(可以从 test 文件的内容入手). 具体实现的过程中思考下列问 题: echo echo Shell Start 与 echo
echo Shell Start
效果是否有区别; echo echo $c>file1 与 echoecho $c>file1
效果是否有区别.
-
解:
-
command:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21!/bin/bash touch test
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:
1
2
33
2
1 -
-
-
echo echo Shell Start
直接把“echo Shell Start
” 作为字符串输出; -
echo (反顿号)echo Shell Start(反顿号)
是将 “echo Shell Start
” 的输出作为 外层echo 的输入,故会输出Shell Start
; -
echo (单引号)echo Shell Start(单引号)
直接把“echo Shell Start
” 作为字符串输出。
-
-
-
echo echo $c>file1
直接把“echo $c>file1
” 作为字符串输出; -
echo (反顿号)echo $c>file1(反顿号)
是将 “echo $c>file1
” 的输出作为 外层echo 的输入,故会输出$c>file1
; -
echo (单引号)echo $c>file1(单引号)
直接把“$c>file1
” 作为字符串输出。
-
-
-
难点分析
对于实验中的难点,可用示意图、流程图或思维导图的方式来表述清楚。
Exercise 0.1
Lab0 第一道练习题包括以下四题,如果你四道题全部完成且正确,即可获得 50 分。
1、在 Lab0 工作区的 src 目录中,存在一个名为 palindrome.c 的文件,使用刚刚学 过的工具打开 palindrome.c,使用 c 语言实现判断输入整数 n(1 ≤ n ≤ 10000) 是否为回 文数的程序 (输入输出部分已经完成)。通过 stdin 每次只输入一个整数 n,若这个数字为 回文数则输出 Y,否则输出 N。[注意:正读倒读相同的整数叫回文数]
2、在 src 目录下,存在一个未补全的 Makefile 文件,借助刚刚掌握的 Makefile 知 识,将其补全,以实现通过 make 命令触发 src 目录下的 palindrome.c 文件的编译链接 的功能,生成的可执行文件命名为 palindrome。
3、在 src/sh_test 目录下,有一个 file 文件和 hello_os.sh 文件。hello_os.sh 是一个未完成的脚本文档,请同学们借助 shell 编程的知识,将其补完,以实现通过命令 bash hello_os.sh AAA BBB,在 hello_os.sh 所处的目录新建一个名为 BBB 的文件,其 内容为 AAA 文件的第 8、32、128、512、1024 行的内容提取 (AAA 文件行数一定超过 1024 行)。[注意:对于命令 bash hello_os.sh AAA BBB,AAA 及 BBB 可为任何合法文件的名 称,例如 bash hello_os.sh file hello_os.c,若已有 hello_os.c 文件,则将其原有 内容覆盖]
4、补全后的 palindrome.c、Makefile、hello_os.sh 依次复制到路径 dst/palindrome.c, dst/Makefile, dst/sh_test/hello_os.sh [注意:文件名和路径必须与题目要求相同]
- 由
.c
文件得到可执行文件:gcc -o palindrome palindrome.c
- 提取
AAA
文件的第8行到BBB
文件中:sed -n '8p' AAA > BBB
(安静模式,且仅输出不编辑)
Exercise 0.2
Lab0 第二道练习题包括以下一题,如果你完成且正确,即可获得 12 分。
在 Lab0 工作区 ray/sh_test1 目录中,含有 100 个子目录 file1~file100,还存 在一个名为 changefile.sh 的文件,将其补完,以实现通过命令 bash changefile.sh, 可以删除该目录内 file71~file100 共计 30 个子目录,将 file41~file70 共计 30 个子 目录重命名为 newfile41~newfile70。[注意:评测时仅检测 changefile.sh 的正确性]
用shell删除叫做file70
~file100
的子目录:rm -r ./"file$a"
($a是shell中的变量)
重命名filexx
为newfilexx
:mv ./"file$a" ./"newfile$a"
让变量$a
递增:let a=a+1
Exercise 0.3
Lab0 第三道练习题包括以下一题,如果你完成且正确,即可获得 12 分。
在 Lab0 工作区的 ray/sh_test2 目录下,存在一个未补全的 search.sh 文件, 将其补完,以实现通过命令 bash search.sh file int result,可以在当前目录下生成 result 文件,内容为 file 文件含有 int 字符串所在的行数,即若有多行含有 int 字符 串需要全部输出。[注意:对于命令 bash search.sh file int result,file 及 result 可为任何合法文件名称,int 可为任何合法字符串,若已有 result 文件,则将其原有内容 覆盖,匹配时大小写不忽略]
输出文件file
中所有含有sign
字符串的行号到文件answer
中:
1 | touch helpfile #another file help me to finsh |
Exercise 0.4
Lab0 第四道练习题包括以下两题,如果你均完成且正确,即可获得 26 分。
1、在 Lab0 工作区的 csc/code 目录下,存在 fibo.c、main.c,其中 fibo.c 有点小 问题,还有一个未补全的 modify.sh 文件,将其补完,以实现通过命令 bash modify.sh fibo.c char int,可以将 fibo.c 中所有的 char 字符串更改为 int 字符串。[注意:对 于命令 bash modify.sh fibo.c char int,fibo.c 可为任何合法文件名,char 及 int 可以是任何字符串,评测时评测 modify.sh 的正确性,而不是检查修改后 fibo.c 的正确 性]
2、Lab0 工作区的 csc/code/fibo.c 成功更换字段后 (bash modify.sh fibo.c char int),现已有 csc/Makefile 和 csc/code/Makefile,补全两个 Makefile 文件,要求在 csc 目录下通过命令 make 可在 csc/code 目录中生成 fibo.o、main.o,在 csc 目录中 生成可执行文件 fibo,再输入命令 make clean 后只删除两个.o 文件。[注意:不能修改 fibo.h 和 main.c 文件中的内容,提交的文件中 fibo.c 必须是修改后正确的 fibo.c, 可执行文件 fibo 作用是输入一个整数 n(从 stdin 输入 n),可以输出斐波那契数列前 n 项,每一项之间用空格分开。比如 n=5,输出 1 1 2 3 5]
要求成功使用脚本文件 modify.sh 修改 fibo.c,实现使用 make 命令可以生成.o 文 件和可执行文件,再使用命令 make clean 可以将.o 文件删除,但保留 fibo 和.c 文件。
-
把
file
文件中的所有wrong
字符串全部替换成correct
字符串:1
2sed -i "s/wrong/correct/g" file
-i只编辑不输出 /g把每一个都这样替换,而不是仅仅每行第一个 -
-
main.c
会调用fibo.c
文件,预处理、编译、汇编、链接步骤如下:-
预处理、编译、汇编
fibo.c
的头文件放在../include
目录里面,则生成fibo.o
和main.o
的Makefile
如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#第一种写法:
all: fibo main
fibo: fibo.c
gcc -E fibo.c -o fibo.i
gcc -S fibo.i -o fibo.s
gcc -c fibo.s -o fibo.o
rm fibo.i
rm fibo.s
main: main.c fibo.o
gcc -E main.c -o main.i -I ../include #Attention!
gcc -S main.i -o main.s
gcc -c main.s -o main.o
rm main.i
rm main.s
#第二种写法(精简):
all: fibo main
fibo: fibo.c
gcc -c fibo.c
main: main.c fibo.o
gcc -c main.c -I ../include #Attention! -
链接
生成可执行文件
Main
如下:1
gcc fibo.o main.o -o Main
-
-
在
csc
目录下通过命令make
可在csc/code
目录中利用csc/code/Makefile
生成fibo.o
、main.o
,在csc
目录中 生成可执行文件fibo
,再输入命令make clean
后只删除两个.o
文件:1
2
3
4
5
6
7
8
9all: fibo
fibo:
cd code && make #一定先cd,再make
gcc ./code/fibo.o ./code/main.o -o fibo
clean:
rm ./code/fibo.o
rm ./code/main.o【Attention:在 Makefile 中 cd 到其他目录,这个 cd 只能有效于当前一行,故而必须使用 “&&” 连接要在 cd 目录下的指令,写在同一行,同时不需要 cd …/ 回来】
-
实验分析
写下实验过程中的体会。
本次实验我参考了一些学长学姐的blog,协助理解几种不同工具的使用,在这里引用Hyggge学长的一幅图,也是我认为几点对我来说有难度或者不熟悉的知识点:
虽然Lab0课下实验的难度不大,但是仍然有许多小细节,具体我写在难点分析中了,课下实验总共花费了15个小时左右,中途也查询了许多资料,并且向同学大牛们请教颇多。
lab0-extra 我最后一个有关diff的操作错误了,正确代码应该是:
我错在写的if [ $? -eq 0 ]
Shell 中,对空格非常敏感,一定要在规定的不同符号间加空格,同时,在Shell中 0 表示真 , 1 表示假!!与正常的编程语言相反!
OS的实验课仍然是道阻且长。
课上测试
本次课上测试,我的lab0-extra
只得了75分,反思确实是自己的相关知识点掌握不到位,因此我觉得是毫无怨言的。
但是稍微有些可惜的是,我和100分失之交臂的点:按照我原本的性格习惯,对于$?
的返回值条件为1或0
(后面会具体讲解),无论怎样我都会尝试一下两种情况的两种结果,但是,在考场上的时候,由于紧张和着急,我没有选择符合之前习惯的做法,其实只要我尝试一下,就是可以满分的,对此感到些许可惜,故而反思到——考场上的心态和冷静依旧是我要培养的点。
通过课后老师的讲解,和与其他同学的交流【主要是笨蛋的我向大牛们请教哇~】,可以发现lab0
的课上测试,在exam
和extra
里面各有一个点卡着大家,这两点甚至老师也要思索一二才能想通,一下具体阐述:
lab0-exam
1 | n=10 |
上面这段程序在本地运行的时候是完全正确的,但是一旦提交到评测机上就会报错,原因是:
-
1. 在
let
语句中,如果=
右边的结果变成小于或等于0的数,那么该let
语句的返回值$?
的值就会变成1; 2. 而在
bash
中,整个程序的返回值$?
=最后一条语句的返回值$?
; 3. 且在评测机中一旦程序的返回值
$?
为1,它就认为这个程序报错了; 故而,上述程序最后的返回值
$?
就是1,则报错。 -
可能的修改方式:
-
第一种方式:
1
2
3
4
5
6
7n=10
i=1
while [ $i -le $n ]
do
echo $i
let i=i+1
done -
第二种方式:
1
2
3
4
5
6n=10
while [ $n -gt 0 ]
do
echo $n
n=$((n-1))
done -
第三种方式:
1
2
3
4
5
6
7n=10
while [ $n -gt 0 ]
do
echo $n
let n=n-1
done
exit 0
-
lab0-extra
diff
-
当
diff A B
发现A和B有不同,那么该语句的返回值$? -eq 1
,并且会输出一定的文字;当A和B完全一样的时候,那么该语句的返回值$? -eq 0
,且不会有任何输出。 -
题目代码为:
1
2
3
4
5
6
7diff $1 $3 > /dev/null
if [ $? -eq 1 ]
then
echo different
else
echo same
fi
$?
$#
$?
表示上一条语句的返回值$#
表示传参个数