【BUAA S4 OS】Lab0 Linux、shell、Git基础操作

2 篇文章 0 订阅

讲解部分梳理

Linux 基本操作

  • head 输出文件首部内容
    • -n <n> 显示前 行内容
    • -c <n> 显示前 个字节内容
  • tail 输出文件尾部内容
    • -n <n> 显示末尾 行内容
    • -c <n> 显示末尾 个字节内容
    • -f 当文件增长时,输出后续添加的数据(适用于文件不断变化的情况,如日志文件)
  • ps 显示当前进程状态
    • -aux / -ef 显示所有进程
  • mv 还可以用于重命名
  • 递归参数
    • -p 从指定目录向上级目录递归 eg 创建目录
    • -r 从指定目录向其下级目录递归 eg 递归删除、拷贝
  • 在命令后加上&符号,代表让命令在后台进行
  • Ctrl Q 进入块选模式,方便删注释和缩进
    • 选择之后可以通过 I 进入插入模式,方便段落缩进
    • { } 向上/下选中 1 段

Makefile 补充

  • 开头最好写.PHONY xx (一般会写.PHONY:clean

    • .PHONY后面跟的目标都被称为伪目标,对应的命令一定会被执行
    • 作用:避免伪目标同名文件冲突;提高执行效率
  • 每一个指令 (command) 之前必须按一次制表符键来控制间隔,而不能是空格,否则 make 会报错

  • 简洁高效的写法

    # 使用变量维护Makefile
    # %.o: %.c 缩小编写量
    CC = gcc
    OBJ = function.o test.o
    TARGET = test
    
    $(TARGET): $(OBJ)
    	$(CC) $(OBJ) -o $(TARGET)
    
    %.o: %.c
    	$(CC) -c $< -o $@
    
  • 外层 makefile 调用内层 makefile

    all:
        $(MAKE) -C subdir
    
    clean:
    	$(MAKE) clean -C subdir
    

Git 补充

git branch

git branch <branch-name> 本地创建一个基于当前分支产生的分支。

git status

查看当前分支的状态,以及当前工作区的变动和暂存区的内容

git add

把一个新文件或者已经修改过的文件加入暂存区

git add <file_name>         # 将指定文件加入暂存区
git add .                   # 或使用.将项目所有文件加入暂存区(除.gitignore指定的文件外)

git restore

放弃修改(如果涉及到文件的增删,建议用 reset,用的时候慎重)

  • 当文件还没有通过 git add 加入暂存区时,使用 git restore <filename> 来撤销修改,使其退回到上一个 commit 的状态
  • 如果文件已经加入了暂存区,通过 git restore **--staged** <filename> 来取消暂存。
  • 其他错误回退命令
    • 若文件未添加至暂存区:使用 git checkout <filename> 将文件替换成暂存区版本,或 git checkout . 将工作区内的所有文件替换成暂存区内的文件(谨慎使用)
    • 若文件已添加到暂存区但未提交到本地仓库:使用 git reset HEAD . 撤销暂存区的所有修改至工作区,接下来就回到了上一步
    • 若已提交到本地仓库:使用 git reset --hard HRAD^ 将所有文件回退至上一版本

git reset

git reset --hard 可以恢复文件的版本,既可以往旧版本恢复,也可以往新版本“恢复”。但–hard 是 reset 命令唯一的危险用法,使用时如果工作区的文件还未提交,git 会覆盖它从而导致无法恢复。所以使用时要小心谨慎

git checkout

切换分支

注意,在切换时,需要保证目前所有文件的状态均为“未修改”(没有修改过,或者已经提交)

git commit

使用 git commit -m <message> 这个命令将暂存区的修改提交到储存库中。当 message 参数有空格时需要把 message 用引号括起来

git rm

  • --cached 从暂存区删除,但不删除工作区文件,不加则两边都删

删除分支

git branch -d(D) <branch-name> 删除本地对应分支

git push origin --delete [branch_name] 删除远程分支

建立孤儿分支

  1. git checkout --orphan <branch name> 创建孤立分支
  2. git rm -rf . 删除拷贝的所有文件
  3. touch add commit
  4. git push -u origin <branch name> 创建远程分支并将其关联

提交空文件夹

Git 只对跟踪文件进行版本控制,而不跟踪文件夹本身。如果想要提交一个空文件夹到 Git 仓库中,可以在文件夹中添加一个占位文件,例如“.gitkeep”

合并分支

git merge 自动合并

  • 如果自动合并不成功(存在冲突)
    • 不想继续合并了,退出合并的中间状态
      git merge --abort
      
    • 处理冲突 最好在图形化界面上解决,更方便
      1. git status查看冲突的文件
      2. 编辑冲突文件,解决冲突(记得删除三行分隔线)
      3. git add 冲突文件
      4. git commit -m "提交信息"

文本处理三剑客

grep 查找

grep [选项] PATTERN FIL
选项(常用):
-a 不忽略二进制数据进行搜索。
-i 忽略大小写差异。
-r 从目录中递归查找。
-n 显示行号
-q 安静模式,不打印结果

sed 替换、删除等

sed [选项] '命令' 输入文本
选项(常用):
-n:安静模式,只显示经过sed处理的内容。否则显示输入文本的所有内容。
**-i:直接修改读取的档案内容,而不是输出到屏幕。否则,只输出不编辑。
-E 选项用于启用扩展正则表达式,这样我们就可以使用更加灵活的正则表达式语法。**
命令(常用):
[行号]a[内容]:新增,在行号后新增一行相应内容。行号可以是“数字”,在这一行之后新增,
 也可以是“起始行,终止行”,在其中的每一行后新增。当不写行号时,在每一
 行之后新增。使用$表示最后一行。后面的命令同理。
[行号]c[内容]:取代。用内容取代相应行的文本。
[行号]i[内容]:插入。在当前行的上面插入一行文本。
[行号]d:删除当前行的内容。
[行号]p:输出选择的内容。通常与选项-n一起使用。
s/re(正则表达式)/string(/g):将re匹配的内容替换为string /g表示全文替换,不加则替换第一个

常用用法

awk '$1>2 {print $1,$3}' my.txt
# awk 'pattern action' file ,pattern 为条件,action 为命令,file 为文件
# 命令中出项的 $n 代表每一行中用空格分隔后的第 n 项
# 该命令的意义是文件 my.txt 中所有第一项大于 2 的行,输出第一项和第三项

awk -F, '{print $2}' my.txt
# -F 选项用来指定用于分隔的字符,默认是空格
# 该命令的意义是打印用 , 分隔后的第 2 项

grep -n "all" my.txt > result.txt
# 打印含有“all”的行并显示行号

sed -i "s/$2/$3/g" $1
# 将传入的第一个参数(文件)里的所有 第二个参数 替代为 第三个参数

shell 编程注意

  • 首句#!/bin/bash

  • 等号与运算符两边不允许有空格,-op的两边与[]内部两边必须有空格

  • 获取变量值建议使用 ${var},花括号避免歧义

  • 引用变量必须在双引号中进行

  • $# 传递的参数个数;$* 一个字符串,内容是传递的全部参数

  • let 赋值运算 eg let i=i+1 等价于 i=$(($i+1)) (双括号是计算值)

  • 流程控制

    if [ 表达式1 ]; then
    	命令列表1;
    elif [ 表达式2 ]; then
    	命令列表2;
    else [ 表达式3 ]; then
    	命令列表3;
    fi
    
    while [ 表达式 ];do
    	命令列表;
    done
    
    for name in [参数列表];do
    	命令列表;
    done
    #最后都有done
    

Lab0

踩坑

在评测前先确保自己对于文件的变更已经全部添加到暂存区(使用合适的 git addgit commit )!!注意先addcommit ,新建的文件需要先添加跟踪才会到暂存区,才能用commit提交。

  • 整型转字符串 sprintf
        int n;
        scanf("%d",&n);
        char str[20];
        sprintf(str,"%d",n);
        printf("%s",str)
    
  • 三剑客不熟悉
  • 变量使用忘了
    自增操作!
    #错误写法
    a=a+1
    #正确写法
    a=$[$a+1]
    
  • 在 sed 命令中
    • 使用变量时,正则用双引号(一般只能用单引号)
      #!/bin/bash
      name=tomas
      sed -i "s/rose/${name}/g" name.txt
      
      • 单引号‘’
        • 括起来的字符均作为普通字符出现
      • 双引号“”
        • 括起来的字符除 $\‘’、和 “” 之外都将作为普通字符对待,所以如果要用变量值就要用“”
      • 倒引号````
        用于命令替换,其所括字符串在被 Shell 解释时,首先执行其中的命令并将其结果代替该命令
      • 俩小括号 / 俩小括号/ 俩小括号/中括号计算结果替换,$单小括号执行结果替代
    • 要更改源文件内容要加参数-i
      # 替换字符串,并更改原文件内容
      # 在sed后面加 -i,即编辑文档“edit files in place”选项
      
  • gcc 编译时如果头文件不在/usr/include里,一定记得-I <头文件所在位置路径>

难点分析

Linux 下命令种类多,参数复杂

  • lsmvtouch等常用命令倒是能熟练掌握,但像sedawk等参数复杂功能复杂的命令,在使用时就容易一下想不起来正确的使用方法
  • 解决方法:先通过多练习熟练,使用时若不确定先查阅资料或参考书

shell 编程中符号和空格使用非常容易出错

比如

  • 各种引号的使用
    • 单引号‘’
      括起来的字符均作为普通字符出现
    • 双引号“”
      括起来的字符除 $\‘’、和 “” 之外都将作为普通字符对待,所以如果要用变量值就要用“”
    • 倒引号````
      用于命令替换,其所括字符串在被 Shell 解释时,首先执行其中的命令并将其结果代替该命令
  • 各种括号的使用
    • $(())/$[]计算结果替换,$()执行结果替代
  • 空格的使用
    • 等号与运算符两边不允许有空格,-op的两边与[]内部两边必须有空格

Makefile 嵌套

  • makefile 嵌套的写法有很多,用$(Make) -C subdir-C 是跳转到指定路径再执行 make 操作) 或者 cd subdir && make 都可以,需要特别注意不要用混了
  • $(Make)这种操作时想要做 make clean,是$(MAKE) clean -C subdir
  • gcc编译时如果依赖的库文件不在本文件夹下,要记得用-I进行链接
  • 注意相对路径和绝对路径的使用要准确

体会

编写 Shell 脚本和 make 文件时熟练度至关重要

虽然上学期学习了系统编程,有了一定的编写 Shell 脚本和 make 文件的基础。但由于课后自主训练较少,加上假期疏于复习,导致对相关操作并不完全熟练。但 Shell 脚本和 make 文件的编写是在 Linux 环境下顺利进行实验的基础,因此需要在课后多多练习,尽快熟悉相关操作,以免后续实验中因基础操作不熟练浪费时间

debug 时利用好讨论区 & 利用好git操作

Excecise1 测评错误后,一直以为是自己哪里写错,反复检查每个文件,提交了 4、5 次,折腾了快 2 个小时还是错误。后来用git status才发现是没有用git add对新建的文件添加跟踪,导致一直没能把这部分文件成功提交 😢

后来在看讨论区时,更是发现一篇精华帖的开头就用大写加粗强调了这个问题……

exam 前准备

血泪教训

  • 在 bash 中,整个程序的返回值 ? = 最后一条语句的返回值 ?=最后一条语句的返回值 ?=最后一条语句的返回值?;且在评测机中一旦程序的返回值$?为 1,它就认为这个程序报错了;
    故最好在每一个脚本文件末尾都手动写一个exit 0
    • $?表示上一条语句的返回值;$#表示传参个数

不熟操作

  • 输出 hello.c 中所有包含“os_hello”(区分大小写)的行的“os_hello”(区分大小写)以左的内容,如果一行出现多个,则输出第一次出现以左的部分
    • grep & sed
      grep -E '.*os_hello' hello.c | sed -E 's/(.*)os_hello.*/\1/'
      
    • awk (两种均可)
      awk -F 'os_hello' '{print $1}' hello.c
      awk '/os_hello/ { sub(/os_hello.*/, ""); print }' hello.c
      
  • #var 是获取变量的长度,${#var}获取长度值
  • 字符串切片操作
    ${variable:start:count} 表示从变量 variablestart 位置开始,截取 count 个字符

  • 多层if容易忘记闭合fi
  • >> 追加会自动换行,想要不换行echo-n xx >> xx
  • $?返回值为 0 表示上一条命令执行成功,1 表示执行失败

exam & extra 复盘

踩的坑(现场解决)

  • 编写脚本文件时,想要输出文件内容,不能用 more 要用 cat
    • more 是交互式的命令,一般在终端直接使用

知识漏洞(现场没解决)

  • 书写条件判断语句时注意!debug 时优先检查条件判断是否出错!
    • less than,应该是-lt 不是 -le 🥲

awk 用法补充

  • awk + if
    awk '{if($2=="'$PID'") print $3}' $FILE
    
    • if 语法和正常语法比较像,if() 后加空格,之后直接写命令(多为 print
  • 在 awk 中使用在 shell 中定义的变量
    使用"'把 shell 变量包起来,即"'$var'";注意是“双引号+单引号+shell 变量+单引号+双引号”的格式
  • 将 awk 结果赋值给变量
    使用倒引号,如var=`echo $result|awk '{print substr($result,16,3)}'
  • 50
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值