os-lab0实验报告


lab0

思考题

Thinking 0.1

  • 在前述已初始化的 ~/learnGit 目录下,创建一个名为 README.txt 的文件。执 行命令 git status > Untracked.txt(其中的 > 为输出重定向,我们将在 0.6.3 中 详细介绍)。

    image-20240313183854380

  • README.txt文件中添加任意文件内容,然后使用 add 命令,再执行命令 git status > Stage.txt

    image-20240313184010190

  • 提交 README.txt,并在提交说明里写入自己的学号

    image-20240313184040344

  • 执行命令 cat Untracked.txtcat Stage.txt,对比两次运行的结果,体会 README.txt 两次所处位置的不同。

    image-20240313184130590

    不一样。第一次是在工作区添加了文件,没有提交的暂存区。而第二次提交到了暂存区,只是没有commit到HEAD。而由于都没有进行commit ,因此都没有跟踪,于是提示是为跟踪的文件。

Thinking 0.2

  • 仔细看看0.10,思考一下箭头中的 add the file 、 stage the file 和commit 分别对应的是 Git 里的哪些命令呢?

    image-20240314115041772

    add the file : 对应git add

    stage the file : 对应git commit

    commit : 对应git checkout

Thinking 0.3

  • 代码文件 print.c 被错误删除时,应当使用什么命令将其恢复?

    image-20240314121507355

    使用 git restore print.c即可

  • 代码文件 print.c 被错误删除后,执行了 git rm print.c 命令,此时应当使用什么命令将其恢复?

    image-20240314142825497

    git restore --staged print.c
    git restore print.c
  • 无关文件 hello.txt 已经被添加到暂存区时,如何在不删除此文件的前提下将其移出暂存区?

    image-20240314143326431

    使用git restore --staged hello.txt即可

Thinking 0.4

  • 找到在 /home/22xxxxxx/learnGit 下刚刚创建的 README.txt 文件,若不存在则新建该文件

  • 在文件里加入 Testing 1, git add, git commit,提交说明记为 1。

  • 模仿上述做法,把 1 分别改为 2 和 3,再提交两次。

    image-20240314160243954

  • 使用 git log 命令查看提交日志,看是否已经有三次提交,记下提交说明为3 的哈希值

    image-20240314160309950

    进行操作后可以看到确实有了三次提交的记录

  • 进行版本回退。执行命令 git reset --hard HEAD^ 后,再执行 git log,观察其变化

    image-20240314160417333

    此时git log的第一项是2,相当于撤销了第三次提交

  • 找到提交说明为 1 的哈希值,执行命令 git reset --hard 后,再执行 git log,观察其变化。

    image-20240314160510381

    强制撤销到1时候的版本,因此git log只能看到1的提交记录

  • 现在已经回到了旧版本,为了再次回到新版本,执行 git reset --hard ,再执行 git log,观察其变化。

    image-20240314161613264

    可以看到又恢复了原样,也就是回到了新版

Thinking 0.5

  • 执行如下命令,并查看结果

    • echo first
    • echo second > output.txt
    • echo third > output.txt
    • echo forth >> output.txt

    image-20240314161945989

    >是覆盖写入

    >>是追加指令

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 效果是否有区别

    image-20240314162443513

    image-20240314162939850

    前两条指令的效果是有区别的,而后两条指令的效果是没有区别

    加上反引号相当于将反引号的内容重定向作为参数

    因此

    echo Shell Start # 标准输出为Shell Start
    echo `echo Shell Start` # 后面指令的标准输出为Shell Start ,作为echo的参数,因此输出还是Shell Start

    c=3
    echo echo $c>file1 # 相当于是echo指令输出了echo $c,其中$c 为 3,然后重定向到文件中
    echo `echo $c>file1`# 相当于是首先`echo $c>file1` ,将$c的值重定向到了file1中,标准输出为空,将标准输出作为前面的echo的参数,因此输出为空,但是echo会默认添加一个换行符,因此还有一个换行

难点分析

CLI

第一个难点在于如果之前习惯了使用GUI界面,刚开始接触这种命令行界面是不够熟悉的。

依稀记得自己第一次接触ubuntu时探索了好久好久,当时使用的还是图形化界面。

命令行界面(CLI)是基于文本的界面,可以在其中输入与计算机操作系统交互的命令。CLI在默认Shell的帮助下运行,该Shell位于操作系统和用户之间。

Shell负责处理各种任务,例如命令解析、环境管理和流程执行等。

此外还可以自定义Shell环境。为此,可以设置环境变量、定义别名(较长命令的快捷方式等)以及为自动化或重复任务创建Shell脚本。

  • 命令的工作原理

在CLI中输入命令是,系统会执行以下步骤:

  1. Shell命令行解释器解析输入的命令以了解其结构,并且分离命令名称、选项和参数
  2. Shell在其可用命令列表中查找命令名称。命令名称代表用户希望操作系统执行的操作
  3. Shell搜索系统的PATH变量(系统文件所在的目录列表),以查找与该命令关联的相应文件
  4. CLI Shell会调用相应的文件,并且传递任何指定的选项和参数作为输入。
  5. 操作系统执行所需的操作
  6. 此操作可能会生成输出,例如信息性消息、错误消息、请求的数据或操作结果
  7. CLI Shell会显示输出,因此可以看到命令的结果

CLI Shell循环运行,等待输入另一条指令。

Linux

Linux与Windows命令行的一些指令的差异可能会让人感到措手不及。比如bash的指令和powershell以及cmd的指令是有比较大的差异的可能让人感到不熟悉。

同时也不熟练的使用Linux的一些基本操作。包括sudo

Vim

由于使用CLI的缘故,我们没有很好的图形化文本编辑器,于是需要使用Vim或者emacs等文本编辑工具。

对于Vim的快捷键以及工作模式不熟悉会带来比较大的难点。

对此我强烈推荐跟着vimtutor走一遍,基本上可以熟悉大多数的操作,以及基本的几个vim模式

image-20240314174337175

image-20240314174412381

image-20240314174441142

image-20240314174505883

image-20240314174529894

image-20240314174700133

image-20240314174717116

其实简单的用法也只有

  • 输入i进入编辑模式
  • 点击Esa退出编辑模式
  • 输入:w保存,:wq保存并退出

基本上可以完成最基本的使用,甚至上下左右可以直接使用箭头键,都不需要使用到hjkl

GCC

对于gcc的基本使用指令不够了解。

tldr是个非常好用的命令用法查询工具,狠狠种草

image-20240314175039544

可以看到gcc的基本用法

  • gcc是一个C语言编译器
  • g++是一个C++语言编译器
语法:gcc [选项]... [文件]...
选项:
-c 仅编译,不链接
-o 指定输出文件
-E 预处理
-S 汇编
-l 指定库文件
-L 指定库文件路径
-I Path/to/head/file 指定头文件路径
-D 定义宏
-wall 显示所有警告
-g 生成调试信息
-std=c99 指定C语言标准
参数:
file.c 源文件

示例

gcc -o hello_world hello_world.c  #编译hello_world.c文件为hello_world可执行文件
gcc -c hello_world.c  #编译hello_world.c文件为hello_world.o目标文件
gcc -E hello_world.c  #预处理hello_world.c文件
gcc -S hello_world.c  #汇编hello_world.c文件
gcc -o hello_world hello_world.c -lm  #编译hello_world.c文件为hello_world可执行文件,并链接数学库

同时编译多个文件

gcc -o hello_world hello_world.c hello_world2.c  #编译hello_world.c和hello_world2.c文件为hello_world可执行文件
gcc -c hello_world.c hello_world2.c  #编译hello_world.c和hello_world2.c文件为hello_world.o和hello_world2.o目标文件

选项-o用于指定要生成的结果文件,后面跟的就是结果文件名字。o是output的意思,不是目标的意思。结果文件可能是预处理文件、汇编文件、目标文件或者最终可执行文件。

Git

git真是一个非常好用的版本管理工具,发明者太强了没办法!

相信同学们经过oopre后基本上对于git的基本用法已经了如指掌了,这里包括

  • git add . 添加修改文件到暂存区
  • git commit -m “message”提交文件到版本库
  • git push 提交到远程仓库

同时还包括一些基本的分支的操作

  • git checkout -b new_branch

但是git的更多高阶的用法其实还是不够熟悉,大多数还是需要查询相关资料进行使用。

这里推荐一个可视化git学习网站:Learn Git Branching

同时我这里整理了一下一些git 常用的指令

基本操作

  • git init初始化一个仓库
  • git clone克隆一个仓库
  • git add添加文件到暂存区
  • git commit提交文件到仓库
  • git status查看仓库状态
  • git diff查看文件差异
  • git log查看提交日志
  • git reset重置仓库
  • git rm删除文件
  • git mv移动文件
  • git branch查看分支

分支操作

  • git branch查看分支
  • git checkout切换分支
  • git merge合并分支
  • git rebase变基分支
  • git cherry-pick挑选提交
  • git tag标记提交
  • git stash暂存工作区
  • git fetch获取远程分支
  • git pull拉取远程分支
  • git push推送远程分支
  • git remote管理远程仓库
  • git submodule管理子模块
  • git worktree管理工作树
  • git reflog查看引用日志
  • git bisect二分查找
  • git blame查看文件作者
  • git grep查找文件内容
  • git log查看提交日志
  • git show查看提交详情

高级操作

  • git filter-branch过滤分支
  • git subcommand子命令
  • git rerere重用冲突解决
  • git gc垃圾回收
  • git fsck检查仓库
  • git prune删除无用对象

git 版本回退

  • git reset --hard HEAD^回退到上一个版本
  • git reset --hard HEAD^^回退到上上一个版本
  • git reset --hard HEAD~100回退到上100个版本
  • git reset --hard commit_id回退到指定版本
  • git reflog查看命令历史
  • git reset --hard commit_id回退到指定版本
  • git reset --hard HEAD@{n}回退到指定版本
  • git reset --hard ORIG_HEAD回退到上一个版本
  • git reset --hard回退到上一个版本

配置

  • git config --global user.name "Your Name"设置用户名
  • `git config --global user.email "
  • git config --global core.editor "vim"设置编辑器
  • git config --global merge.tool "vimdiff"设置合并工具
  • git config --global color.ui true设置颜色
  • git config --global alias.st status设置别名
  • git config --global alias.co checkout设置别名
  • git config --global alias.ci commit设置别名
  • git config --global alias.br branch设置别名
  • git config --global alias.unstage "reset HEAD"设置别名

Shell脚本

这个对于我自己来说也是一个比较大的难点!!主要对于一些特殊字符的用法不了解,其中包括小括号,中括号,大括号,单引号,反引号,双引号

我觉得把这个讲清楚真的非常重要,其次就是了解一些基本的变量、控制结构(条件结构,循环结构)基本上就能够懂得基本的用法了

其中稍微高阶一点,也是shell作为一个脚本型语言的特色就是其参数传递了

同时还有一些比较困难的指令的使用,包括grep awk sed

虽然可以通过man来了解大部分

shell脚本

shell脚本是一个用于执行命令的脚本文件

  • 在脚本中在第一行添加#!/bin/bash可以指定脚本使用的shell
  • 运行脚本
    • 通过chmod +x script.sh添加执行权限后,./script.sh运行脚本
    • sh script.sh运行脚本
    • ./script.sh运行脚本
    • source script.sh运行脚本
  • 参数
    • $0脚本名
    • $1第一个参数
    • $2第二个参数
    • $#参数个数
    • $*所有参数,所有参数都是一个字符串
    • $@所有参数,每个参数都是一个独立的字符串
    • $$脚本的进程号
    • $?上一个命令的返回值
    • $!后台运行的最后一个进程的进程号
  • 函数
    • function_name(){...}定义函数
    • function_name调用函数
    • return返回值
  • 控制结构
    • if...then...fi条件语句
    • case...esac多条件语句
    • for...do...done循环语句
    • while...do...done循环语句
    • until...do...done循环语句
    • break跳出循环
    • continue跳过本次循环
    • exit退出脚本
    • trap捕获信号
    • eval执行命令
    • exec执行命令
    • let执行算术运算
    • select选择语句
    • shift移动参数
    • source执行脚本
    • test测试语句
    • time计时
    • type查找命令
    • ulimit设置资源限制
  • 关系运算符
    • -eq等于
    • -ne不等于
    • -gt大于
    • -lt小于
    • -ge大于等于
    • -le小于等于
    • =字符串相等
    • !=字符串不相等
    • -z字符串为空
    • -n字符串不为空
    • -e文件存在
    • -f文件存在且是普通文件
    • -d文件存在且是目录
    • -s文件存在且不为空
    • -r文件存在且可读

grep

image-20240314180342701

awk

image-20240314180412634

sed

image-20240314180442171

实验体会

我觉得通过本次实验自己对于一些工具包括vim tmux更加熟悉了,同时对于shell脚本的撰写也更加熟悉了。学到了很多东西!!!

当然还有一点体会就是对于命令的细节还是要更加了解一点,比如echo会自动加入换行符,真的被狠狠背刺了啊啊啊啊!!

前面没有提到,这里分享一下自己学习tmux的经验

tmux is terminal multiplexer

虽然你可以打开多个终端,但是tmux帅啊!!

创建会话 creating tmux sessions

tmux

这样会打开一个新的页面也该窗口

image-20240308144341753

退出

exit

增加一个命名:

tmux new -s test

image-20240308144443438

创建新的tmux窗口creating new tmux windows

Ctrl-b c

Ctrl-b在tmux里面相当于是一个命令前缀

image-20240308144816204

在两个tmux窗口之间切换 switching between tmux windows

Ctrl-b n

这样会顺序遍历已经创建的窗口

Ctrl-b 2

你可以注意到这个窗口的名字叫做bash,是因为目前是正在运行进程,如果你某一个窗口运行htop,那么那个窗口的名字就是htop

如果你想要设置一个不会改变的窗口命名

Ctrl-b ,

image-20240308150121933

离开一个会话detaching from a tmux session

Ctrl-b d

连接一个会话attaching to a tmus session

tmux a

如果需要重新新建一个任务可以

Ctrl-b new -s coding
// 也就是前面的新建一个session的操作

image-20240308150456377

列举所有tmux会话listing tmux sessions

tmux ls

如果想要连接某一个session,可以

tmux a -t test

image-20240308150641122

可以再几个session之间切换

Ctrl-b s

image-20240308150751219

窗格操作

划分窗格

tmux split-window命令用来划分窗格。

# 划分上下两个窗格
$ tmux split-window

# 划分左右两个窗格
$ tmux split-window -h

移动光标

tmux select-pane命令用来移动光标位置。

# 光标切换到上方窗格
$ tmux select-pane -U

# 光标切换到下方窗格
$ tmux select-pane -D

# 光标切换到左边窗格
$ tmux select-pane -L

# 光标切换到右边窗格
$ tmux select-pane -R

交换窗格位置

tmux swap-pane命令用来交换窗格位置。

# 当前窗格上移
$ tmux swap-pane -U

# 当前窗格下移
$ tmux swap-pane -D

窗格快捷键

下面是一些窗格操作的快捷键。

  • Ctrl+b %:划分左右两个窗格。
  • Ctrl+b ":划分上下两个窗格。
  • Ctrl+b <arrow key>:光标切换到其他窗格。<arrow key>是指向要切换到的窗格的方向键,比如切换到下方窗格,就按方向键
  • Ctrl+b ;:光标切换到上一个窗格。
  • Ctrl+b o:光标切换到下一个窗格。
  • Ctrl+b {:当前窗格与上一个窗格交换位置。
  • Ctrl+b }:当前窗格与下一个窗格交换位置。
  • Ctrl+b Ctrl+o:所有窗格向前移动一个位置,第一个窗格变成最后一个窗格。
  • Ctrl+b Alt+o:所有窗格向后移动一个位置,最后一个窗格变成第一个窗格。
  • Ctrl+b x:关闭当前窗格。
  • Ctrl+b !:将当前窗格拆分为一个独立窗口。
  • Ctrl+b z:当前窗格全屏显示,再使用一次会变回原来大小。
  • Ctrl+b Ctrl+<arrow key>:按箭头方向调整窗格大小。
  • Ctrl+b q:显示窗格编号。

获取帮助getting help with tmux

Ctrl-b ?

或者使用

man tmux

image-20240308150851773

reference

https://www.ruanyifeng.com/blog/2019/10/tmux.html

https://www.linuxtrainingacademy.com/tmux-tutorial/


文章作者: hugo
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hugo !
  目录