lab0
思考题
Thinking 0.1
-
在前述已初始化的
~/learnGit目录下,创建一个名为README.txt的文件。执 行命令git status > Untracked.txt(其中的 > 为输出重定向,我们将在 0.6.3 中 详细介绍)。
-
在
README.txt文件中添加任意文件内容,然后使用add命令,再执行命令git status > Stage.txt。
-
提交
README.txt,并在提交说明里写入自己的学号
-
执行命令
cat Untracked.txt和cat Stage.txt,对比两次运行的结果,体会README.txt两次所处位置的不同。
不一样。第一次是在工作区添加了文件,没有提交的暂存区。而第二次提交到了暂存区,只是没有commit到HEAD。而由于都没有进行commit ,因此都没有跟踪,于是提示是为跟踪的文件。
Thinking 0.2
-
仔细看看0.10,思考一下箭头中的 add the file 、 stage the file 和commit 分别对应的是 Git 里的哪些命令呢?

add the file : 对应
git addstage the file : 对应
git commitcommit : 对应
git checkout
Thinking 0.3
-
代码文件 print.c 被错误删除时,应当使用什么命令将其恢复?

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

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

使用
git restore --staged hello.txt即可
Thinking 0.4
-
找到在 /home/22xxxxxx/learnGit 下刚刚创建的 README.txt 文件,若不存在则新建该文件
-
在文件里加入 Testing 1, git add, git commit,提交说明记为 1。
-
模仿上述做法,把 1 分别改为 2 和 3,再提交两次。

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

进行操作后可以看到确实有了三次提交的记录
-
进行版本回退。执行命令 git reset --hard HEAD^ 后,再执行 git log,观察其变化

此时git log的第一项是2,相当于撤销了第三次提交
-
找到提交说明为 1 的哈希值,执行命令 git reset --hard
后,再执行 git log,观察其变化。 
强制撤销到1时候的版本,因此git log只能看到1的提交记录
-
现在已经回到了旧版本,为了再次回到新版本,执行 git reset --hard
,再执行 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效果是否有区别

前两条指令的效果是有区别的,而后两条指令的效果是没有区别
加上反引号相当于将反引号的内容重定向作为参数
因此
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中输入命令是,系统会执行以下步骤:
- Shell命令行解释器解析输入的命令以了解其结构,并且分离命令名称、选项和参数
- Shell在其可用命令列表中查找命令名称。命令名称代表用户希望操作系统执行的操作
- Shell搜索系统的PATH变量(系统文件所在的目录列表),以查找与该命令关联的相应文件
- CLI Shell会调用相应的文件,并且传递任何指定的选项和参数作为输入。
- 操作系统执行所需的操作
- 此操作可能会生成输出,例如信息性消息、错误消息、请求的数据或操作结果
- CLI Shell会显示输出,因此可以看到命令的结果
CLI Shell循环运行,等待输入另一条指令。
Linux
Linux与Windows命令行的一些指令的差异可能会让人感到措手不及。比如bash的指令和powershell以及cmd的指令是有比较大的差异的可能让人感到不熟悉。
同时也不熟练的使用Linux的一些基本操作。包括sudo等
Vim
由于使用CLI的缘故,我们没有很好的图形化文本编辑器,于是需要使用Vim或者emacs等文本编辑工具。
对于Vim的快捷键以及工作模式不熟悉会带来比较大的难点。
对此我强烈推荐跟着
vimtutor走一遍,基本上可以熟悉大多数的操作,以及基本的几个vim模式







其实简单的用法也只有
- 输入
i进入编辑模式 - 点击
Esa退出编辑模式 - 输入
:w保存,:wq保存并退出
基本上可以完成最基本的使用,甚至上下左右可以直接使用箭头键,都不需要使用到hjkl。
GCC
对于gcc的基本使用指令不够了解。
tldr是个非常好用的命令用法查询工具,狠狠种草

可以看到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

awk

sed

实验体会
我觉得通过本次实验自己对于一些工具包括vim tmux更加熟悉了,同时对于shell脚本的撰写也更加熟悉了。学到了很多东西!!!
当然还有一点体会就是对于命令的细节还是要更加了解一点,比如echo会自动加入换行符,真的被狠狠背刺了啊啊啊啊!!
前面没有提到,这里分享一下自己学习tmux的经验
tmux is terminal multiplexer
虽然你可以打开多个终端,但是tmux帅啊!!
创建会话 creating tmux sessions
tmux
这样会打开一个新的页面也该窗口

退出
exit
增加一个命名:
tmux new -s test

创建新的tmux窗口creating new tmux windows
Ctrl-b c
Ctrl-b在tmux里面相当于是一个命令前缀

在两个tmux窗口之间切换 switching between tmux windows
Ctrl-b n
这样会顺序遍历已经创建的窗口
Ctrl-b 2
你可以注意到这个窗口的名字叫做bash,是因为目前是正在运行进程,如果你某一个窗口运行htop,那么那个窗口的名字就是htop
如果你想要设置一个不会改变的窗口命名
Ctrl-b ,

离开一个会话detaching from a tmux session
Ctrl-b d
连接一个会话attaching to a tmus session
tmux a
如果需要重新新建一个任务可以
Ctrl-b new -s coding
// 也就是前面的新建一个session的操作

列举所有tmux会话listing tmux sessions
tmux ls
如果想要连接某一个session,可以
tmux a -t test

可以再几个session之间切换
Ctrl-b s

窗格操作
划分窗格
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

reference