MIT-Missing-Semester

课程简介

  • 先修要求:无
  • 编程语言:shell
  • 课程难度:🌟🌟
  • 预计学时:10 小时

正如课程名字所言:“计算机教f学中消失的一个学期”,这门课将会教会你许多大学的课堂上不会涉及但却对每个 CSer 无比重要的工具或者知识点。例如 Shell 编程、命令行配置、Git、Vim、tmuxssh 等等。如果你是一个计算机小白,那么我非常建议你学习一下这门课,因为它基本涉及了本书必学工具中的绝大部分内容。

除了 MIT 官方的学习资料外,北京大学图灵班开设的前沿计算实践中也开设了相关课程,资料位于这个网站下,供大家参考。

课程资源

  • 课程网站:https://missing.csail.mit.edu/2020/
  • 课程视频:https://www.youtube.com/playlist?list=PLyzOVJj3bHQuloKGG59rS43e29ro7I57J
  • 课程作业:一些随堂小练习,具体见课程网站。

基本命令

top(持续监听进程运行状态)

  • -d 秒数:指定 top 命令每隔几秒更新。默认是 3 秒;
  • -b:使用批处理模式输出。一般和"-n"选项合用,用于把 top 命令重定向到文件中;
  • -n 次数:指定 top 命令执行的次数。一般和"-"选项合用;
  • -p 进程PID:仅查看指定 ID 的进程;
  • -s:使 top 命令在安全模式中运行,避免在交互模式中出现错误;
  • -u 用户名:只监听某个用户的进程;

在 top 命令的显示窗口中,还可以使用如下按键,进行一下交互操作:

  • ? 或 h:显示交互模式的帮助;
  • P:按照 CPU 的使用率排序,默认就是此选项;
  • M:按照内存的使用率排序;
  • N:按照 PID 排序;
  • T:按照 CPU 的累积运算时间排序,也就是按照 TIME+ 项排序;
  • k:按照 PID 给予某个进程一个信号。一般用于中止某个进程,信号 9 是强制中止的信号;
  • r:按照 PID 给某个进程重设优先级(Nice)值;
  • q:退出 top 命令;

jobs(后台进程)、

选项含义
-l(L 的小写)列出进程的 PID 号。
-n只列出上次发出通知后改变了状态的进程。
-p只列出进程的 PID 号。
-r只列出运行中的进程。
-s只列出已停止的进程

dpkg --list(查看已安装软件)

# 查看已安装软件
dpkg --list

# 卸载软件
sudo apt remove --purge [name] #卸载软件同时删除配置文件
sudo apt remove [name]  #卸载该软件

好用的工具

vim内插件

ctrlp(vim 内文件树)

image-20221121204804627

  • ctrl + j/k 进行上下选择
  • ctrl + x 在当前窗口水平分屏打开文件
  • ctrl + v 同上, 垂直分屏
  • ctrl + t 在tab中打开
  • ctrl + r字符串模式正则表达式模式 之间切换

NERDTree(文件树)

image-20221201182125369

  • ?: 快速帮助文档
  • o: 打开一个目录或者打开文件,创建的是 buffer,也可以用来打开书签
  • go: 打开一个文件,但是光标仍然留在 NERDTree,创建的是 buffer
  • t: 打开一个文件,创建的是Tab,对书签同样生效
  • T: 打开一个文件,但是光标仍然留在 NERDTree,创建的是 Tab,对书签同样生效
  • i: 水平分割创建文件的窗口,创建的是 buffer
  • gi: 水平分割创建文件的窗口,但是光标仍然留在 NERDTree
  • s: 垂直分割创建文件的窗口,创建的是 buffer
  • gs: 和 gi,go 类似
  • x: 收起当前打开的目录
  • X: 收起所有打开的目录
  • e: 以文件管理的方式打开选中的目录
  • D: 删除书签

auto-pairs(括号自动匹配)

NerdCommenter(注释)

  • \cc 注释当前行和选中行
  • \cu 取消注释
  • \c<space> 如果被选区域有部分被注释,则对被选区域执行取消注释操作,其它情况执行反转注释操作
  • \ci 执行反转注释操作,选中区域注释部分取消注释,非注释部分添加注释
  • \cA 跳转到该行结尾添加注释,并进入编辑模式
  • \cn没有发现和\cc有区别
  • \cm 对被选区域用一对注释符进行注释,前面的注释对每一行都会添加注释
  • \cs 添加性感的注释,代码开头介绍部分通常使用该注释
  • \cy 添加注释,并复制被添加注释的部分
  • \c$ 注释当前光标到改行结尾的内容
  • \ca 转换注释的方式,比如: /**/和//
  • \cl \cb 左对齐和左右对其,左右对其主要针对/**/

fd(文件查找)

shellcheck1(查错)

shellcheck

tldr (Too long; Didn’t read)

image-20221120191539960

rg(riggrep)(在当前文件下文件内查找)

image-20221120193545743

fzf(命令行的模糊搜索)

image-20221120200210604

image-20221120200217174

fish(History存储的command-line)

image-20221120201126673

tree(or broot nnn)(文件树)

image-20221120201107434

sed(脚本编写方式读文本)

#sed

cat file.sh | sed 's/REGEX/SUBSTITUTION/'
# 其中 REGEX 部分是我们需要使用的正则表达式,而 SUBSTITUTION 是用于替换匹配结果的文本。

image-20221122222441207

less(逐页滚动读文本)

# less

less [filename]

image-20221122222756073

perl(文本处理工具[正则])

image-20221123204439531

wc(文本统计工具)

image-20221123210116651

awk(适合处理文本的编程语言)

image-20221123211814842

bc(计算器语言)

image-20221123213912118

xargs(将标准输入作为参数)

kill(终止进程)

kill -STOP[-TERM/-QUIT/-INT] <PID>
# STOP 暂停进程
# INT (Ctrl+C) : 只对当前前台进程,和他的所在的进程组的每个进程都发送SIGINT信号,之后这些进程会执行信号处理程序再终止
# QUIT (Ctrl+\) : 
# TERM : 当前进程会收到信号,而其子进程不会收到.如果当前进程被kill(即收到SIGTERM),则其子进程的父进程将为init,即pid为1的进程(kill <PID>)
# KILL : 当前进程收到该信号,注意该信号时无法被捕获的,也就是说进程无法执行信号处理程序,会直接发送默认行为,也就是直接退出 (kill -9 <PID>)
# HUP : 终止进程(无法终止nohup进程)
SIGHUP     终止进程     终端线路挂断
SIGINT     终止进程     中断进程
SIGQUIT   建立CORE文件终止进程,并且生成core文件
SIGILL   建立CORE文件       非法指令
SIGTRAP   建立CORE文件       跟踪自陷
SIGBUS   建立CORE文件       总线错误
SIGSEGV   建立CORE文件       段非法错误
SIGFPE   建立CORE文件       浮点异常
SIGIOT   建立CORE文件       执行I/O自陷
SIGKILL   终止进程     杀死进程
SIGPIPE   终止进程     向一个没有读进程的管道写数据
SIGALARM   终止进程     计时器到时
SIGTERM   终止进程     软件终止信号
SIGSTOP   停止进程     非终端来的停止信号
SIGTSTP   停止进程     终端来的停止信号
SIGCONT   忽略信号     继续执行一个停止的进程
SIGURG   忽略信号     I/O紧急信号
SIGIO     忽略信号     描述符上可以进行I/O
SIGCHLD   忽略信号     当子进程停止或退出时通知父进程
SIGTTOU   停止进程     后台进程写终端
SIGTTIN   停止进程     后台进程读终端
SIGXGPU   终止进程     CPU时限超时
SIGXFSZ   终止进程     文件长度过长
SIGWINCH   忽略信号     窗口大小发生变化
SIGPROF   终止进程     统计分布图用计时器到时
SIGUSR1   终止进程     用户定义信号1
SIGUSR2   终止进程     用户定义信号2
SIGVTALRM 终止进程     虚拟计时器到时

pkill

Mostly used for stopping processes.

# Kill all processes which match their full command instead of just the process name
pkill -f 'filename'

wait

Wait for a process to complete before proceeding.

image-20221127203916231

tmux(终端多路复用)2

image-20221124221659078

Lecture 1: 课程概览与 shell

local:~$ echo "hello world"
local:~$ echo hello\ world

-> hello world
# 查询环境变量"PATH"
missing:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# 输出命令"echo"的执行路径
missing:~$ which echo
/bin/echo


missing:~$ /bin/echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# print working directory
missing:~$ pwd
/home/missing

# change directory
missing:~$ cd /home
missing:/home$ pwd
/home

# . : current directory
# .. : the parent directory
missing:/home$ cd ..
missing:/$ pwd
/

# ~ : home directory
missing:/home$ cd ~
missing:/home$ pwd
/home

# - : previous directory(前一路径)
# ls -l(= ll)
usr:$ ll
total 30477
-rw-r--r-- 1 BAY 197610    19732 Nov  2 09:54 22_11_05组会.docx
-rw-r--r-- 1 BAY 197610      282 Nov  3 19:19 desktop.ini
-rw-r--r-- 1 BAY 197610     3003 Oct 28 10:13 environment.yml
-rw-r--r-- 1 BAY 197610 31182837 Nov  2 17:14 白澳阳22.11.05组会.pptx
# 九个字符,每三个字符构成一组。 (rwx). 它们分别代表了文件所有者(missing),用户组(users) 以及其他所有人具有的权限
# w-修改 x-可执行 r-读
#  /bin 目录下的程序在最后一组,即表示所有人的用户组中,均包含 x 权限,也就是说任何人都可以执行这些程序。

# mv-重命名或移动 cp-拷贝 mkdir-新建文件夹

# 将程序的文档(用户手册)展现
usr:$ man ls
# 最简单的重定向是 < file 和 > file。这两个命令可以将程序的输入输出流分别重定向到文件:
missing:~$ echo hello > hello.txt
missing:~$ cat hello.txt
hello
missing:~$ cat < hello.txt > hello2.txt

# 您还可以使用 >> 来向一个文件追加内容。
missing:~$ echo hi >> hello2.txt

# | 操作符允许我们将一个程序的输出和另外一个程序的输入连接起来
# 使用管道( pipes ),我们能够更好的利用文件重定向。
missing:~$ ls -l / | tail -n1
drwxr-xr-x 1 root  root  4096 Jun 20  2019 var
missing:~$ curl --head --silent google.com | grep --ignore-case content-length | cut --delimiter=' ' -f2
219
# 查找文件名中类似…h…的文件
find -name "*h*"

# tee: 输入并显示在屏幕上
echo hello | tee hello.txt

chmod

who用户类型说明
uuser文件所有者
ggroup文件所有者所在组
oothers所有其他用户
aall所有用户, 相当于 ugo
Operator说明
+为指定的用户类型增加权限
-去除指定用户类型的权限
=设置指定用户权限的设置,即将用户类型的所有权限重新设置
模式名字说明
r设置为可读权限
w设置为可写权限
x执行权限设置为可执行权限
X特殊执行权限只有当文件为目录文件,或者其他类型的用户有可执行权限时,才将文件权限设置可执行
ssetuid/gid当文件被执行时,根据who参数指定的用户类型设置文件的setuid或者setgid权限
t粘贴位设置粘贴位,只有超级用户可以设置该位,只有文件所有者u可以使用该位
#权限rwx二进制
7读 + 写 + 执行rwx111
6读 + 写rw-110
5读 + 执行r-x101
4只读r–100
3写 + 执行-wx011
2只写-w-010
1只执行–x001
0000

例如, 765 将这样解释:

  • 所有者的权限用数字表达:属主的那三个权限位的数字加起来的总和。如 rwx ,也就是 4+2+1 ,应该是 7。
  • 用户组的权限用数字表达:属组的那个权限位数字的相加的总和。如 rw- ,也就是 4+2+0 ,应该是 6。
  • 其它用户的权限数字表达:其它用户权限位的数字相加的总和。如 r-x ,也就是 4+0+1 ,应该是 5。

Lecture 2: Shell 工具和脚本

# 以'定义的字符串为原义字符串,其中的变量不会被转义,而 "定义的字符串会将变量值进行替换。
foo=bar
echo "$foo"
# 打印 bar
echo '$foo'
# 打印 $foo
$ vim mcd.sh
>
mcd () {
    mkdir -p "$1"
    cd "$1"
}
<

soucrce mcd.sh
mcd test
  • $0 - 脚本名
  • $1$9 - 脚本的参数。 $1 是第一个参数,依此类推。
  • $@ - 所有参数
  • $# - 参数个数
  • $? - 前一个命令的返回值
  • $$ - 当前脚本的进程识别码
  • !! - 完整的上一条命令,包括参数。常见应用:当你因为权限不足执行命令失败时,可以使用 sudo !!再尝试一次。
  • $_ - 上一条命令的最后一个参数。如果你正在使用的是交互式 shell,你可以通过按下 Esc 之后键入 . 来获取这个值。
#!/bin/bash

echo "Starting program at $(date)" # date会被替换成日期和时间

echo "Running program $0 with $# arguments with pid $$"

for file in "$@"; do
    grep foobar "$file" > /dev/null 2> /dev/null
    # > 代表标准输出流
    # 2> 代表标准错误
    # 如果模式没有找到,则grep退出状态为 1
    # 我们将标准输出流和标准错误流重定向到Null,因为我们并不关心这些信息
    if [[ $? -ne 0 ]]; then
        echo "File $file does not have any foobar, adding one"
        echo "# foobar" >> "$file"
    fi
done
convert image.{png,jpg}
# 会展开为
convert image.png image.jpg

cp /path/to/project/{foo,bar,baz}.sh /newpath
# 会展开为
cp /path/to/project/foo.sh /path/to/project/bar.sh /path/to/project/baz.sh /newpath

# 也可以结合通配使用
mv *{.py,.sh} folder
# 会移动所有 *.py 和 *.sh 文件

mkdir foo bar

# 下面命令会创建foo/a, foo/b, ... foo/h, bar/a, bar/b, ... bar/h这些文件
touch {foo,bar}/{a..h}
touch foo/x bar/y
# 比较文件夹 foo 和 bar 中包含文件的不同
diff <(ls foo) <(ls bar)
# 输出
# < x
# ---
# > y
#!/usr/bin/env python3
#!/usr/bin/python3
import sys
for arg in reversed(sys.argv[1:]):
    print(arg)
# find

# 查找所有名称为src的文件夹
find . -name src -type d
# 查找所有文件夹路径中包含test的python文件
find . -path '*/test/*.py' -type f
# 查找前一天修改的所有文件
find . -mtime -1
# 查找所有大小在500k至10M的tar.gz文件
find . -size +500k -size -10M -name '*.tar.gz'
#grep
# grep 有很多选项,这也使它成为一个非常全能的工具。其中我经常使用的有 -C :获取查找结果的上下文(Context);-v 将对结果进行反选(Invert),也就是输出不匹配的结果。举例来说, grep -C 5 会输出匹配结果前后五行。当需要搜索大量文件的时候,使用 -R 会递归地进入子目录并搜索所有的文本文件。

grep foobar mcd.sh
> # foobar

grep -R foobar
>
mcd.sh:# foobar
example.sh:	grep foobar "$file" > /dev/null 2> /dev/null
example.sh:		echo "File $file dose not have any foobar, adding one"
example.sh:		echo "# foobar" >> "$file"

# rg
# 查找所有使用了 requests 库的文件
rg -t py 'import requests'
# 查找所有没有写 shebang 的文件(包含隐藏文件)
rg -u --files-without-match "^#!"
# 查找所有的foo字符串,并打印其之后的5行
rg foo -A 5
# 打印匹配的统计信息(匹配的行和文件的数量)
rg --stats PATTERN
# history

history | grep find

# Ctrl+R
# 敲 Ctrl+R 后您可以输入子串来进行匹配,查找历史命令行。
# 反复按下就会在所有搜索结果中循环。

Lecture 3: Vim

操作模式

Vim 的设计以大多数时间都花在阅读、浏览和进行少量编辑改动为基础,因此它具有多种操作模式:

  • 正常模式:在文件中四处移动光标进行修改(Esc)

  • 插入模式:插入文本(I)

  • 替换模式:替换文本®

  • 可视化模式(一般,行,块):选中文本块(v-V-^v)

  • 命令模式:用于执行命令(😃

    • :q 退出(关闭窗口)

      • :qa 关闭所有窗口
    • :w 保存(写)

    • :wq 保存然后退出

    • :e {文件名} 打开要编辑的文件

    • :ls 显示打开的缓存

    • :help {标题}

      • 打开帮助文档

      :help :w 打开 :w 命令的帮助文档

      :help w 打开 w 移动的帮助文档

标签

vim [filename] 打开文件

vim [num] [filename] 打开文件,定位到第n行

:sp(:split) 竖直打开多个文件

:vsp(:vsplit) 水平打开多个文件

:tabc 关闭当前标签页

  1. 文件间切换

Ctrl+^ 下一个文件

:bn 下一个文件

:bp 上一个文件

  1. 窗格间切换

Ctrl+w+[上下左右] 切换到前/下/上/后一个窗格

Ctrl+w+[hjkl] 切换到前/下/上/后一个窗格

Ctrl+ww 依次切换到下一个窗格中

  1. 多文档便捷

:n 编辑下一个文档。
:2n 编辑下两个文档。
:N 编辑上一个文档。注意,该方法只能用于同时打开多个文档。
:e [filename] 这是在进入vim后,不离开 vim 的情形下打开其他文档。
:e#Ctrl+ˆ 编辑上一个文档,用于两个文档相互交换编辑时使用。?# 代表的是编辑前一次编辑的文档
:files:buffers:ls 可以列出目前 缓冲区 中的所有文档。加号 + 表示 缓冲区已经被修改过了。#代表上一次编辑的文档,%是目前正在编辑中的文档
:b 文档名或编号 移至该文档。
:fCtrl+g 显示当前正在编辑的文档名称。
:f [filename] 改变编辑中的文档名。(file)

移动

多数时候你会在正常模式下,使用移动命令在缓存中导航。在 Vim 里面移动也被称为 “名词”, 因为它们指向文字块。

  • 基本移动: hjkl (左, 下, 上, 右)

  • 词: w (下一个词), b (词初), e (词尾)

  • 行: 0 (行初), ^ (第一个非空格字符), $ (行尾)

  • 屏幕: H (屏幕首行), M (屏幕中间), L (屏幕底部)

  • 翻页(半页): Ctrl-u (上翻半页), Ctrl-d (下翻半页)

  • 翻页一页:Ctrl-f (下翻一页), Ctrl-b(上翻一页)

  • 文件: gg (文件头), G (文件尾)

  • 行数: :{行数}<CR> 或者 {行数}G ({行数}为行数)

  • 杂项: % (找到配对,比如括号或者 /* */ 之类的注释对)

  • 查找:f{字符}t{字符}F{字符}T{字符}

    • 查找/到 向前/向后 在本行的{字符}

    • , / ; 用于导航匹配

  • 搜索: /{正则表达式}, n / N 用于导航匹配

选择

可视化模式:

  • 可视化:v
  • 可视化行: V
  • 可视化块:Ctrl+v

可以用移动命令来选中。

编辑

  • i进入插入模式
    • 但是对于操纵/编辑文本,不单想用退格键完成
  • O / o 在之上/之下插入行
  • d{移动命令}删除 {移动命令}
    • 例如,dw 删除词, d$ 删除到行尾, d0 删除到行头。
    • dd 删除当前行
    • . 重复删除操作
  • c{移动命令}改变 {移动命令}
    • 例如,cw 改变词
    • 比如 d{移动命令}i
  • x 删除字符(等同于 dl
  • r 替换字符(ra 删除并替换成a)
  • s 替换字符(删除并插入)(等同于 xi
  • 可视化模式 + 操作
    • 选中文字, d 删除 或者 c 改变
  • u 撤销
  • <C-r> 重做
  • y 复制 / “yank” (其他一些命令比如 d 也会复制)
  • p 粘贴
  • . 重复之前的编辑操作
  • 更多值得学习的: 比如 ~ 改变字符的大小写
  • << >> 向左/右缩进当前行
  • == 自动排版当前行
  • gg=G 当前文档全文自动排版
  • <N>== 对从当前行开始的 N 行进行自动排版
  • =<N>j 对当前行以及向下 N 行进行自动排版
  • =<N>k 对当前行以及向上 N 行进行自动排版

计数

你可以用一个计数来结合“名词”和“动词”,这会执行指定操作若干次。

  • 3w 向前移动三个词
  • 5j 向下移动5行
  • 7dw 删除7个词

修饰语

你可以用修饰语改变“名词”的意义。修饰语有 i,表示“内部”或者“在内“,和 a, 表示”周围“。

  • ci( 改变当前括号内的内容
  • ci[ 改变当前方括号内的内容
  • da' 删除一个单引号字符串, 包括周围的单引号

Lecture 4: 数据整理

正则表达式

  • . 除换行符之外的”任意单个字符”
  • * 匹配前面字符零次或多次
  • + 匹配前面字符一次或多次
  • [abc] 匹配 a, bc 中的任意一个
  • (RX1|RX2) 任何能够匹配RX1RX2的结果
  • ^ 行首$ 行尾

image-20221123201541763

image-20221123202123598

image-20221123202317083

捕获组

# .*? 只搜索一次
# 一个括号进行一次捕获
# \1 第一次捕获的内容
echo 'abc ab a ab a abc ab a' | perl -pe 's/.*?ab(c| )/\1/'
c ab a ab a abc ab a

排序、过滤(sort|uniq -c)

image-20221123210700038

# sort -nk1,1 : 仅基于以空格分割的第一列进行排序
# head : 从前往后数
# tail : 从后往前数
cat abc.md | perl -pe 's/.*?ab//' | sort | uniq -c | sort -nk1,1 | head -3

处理、同行(awk、paste)

# awk ‘{print $1}’ : 打印第一列
# paste -sd, : 大隐刀同一行并以,分割
cat abc.md | perl -pe 's/.*?ab//' | awk '{print $1}' | paste -sd,
>> c,c,c,c,a,a

计数(bc)

cat abc.md | perl -pe 's/.*?ab//' | sort | uniq -c | awk '{print $1}' | paste -sd+ | bc

image-20221123214146853

Lecture5: 命令行环境

1.任务控制(Job control)

结束进程

shell 会使用 UNIX 提供的信号机制执行进程间通信。当一个进程接收到信号时,它会停止执行、处理该信号并基于信号传递的信息来改变其执行。就这一点而言,信号是一种软件中断

尽管 SIGINTSIGQUIT 都常常用来发出和终止程序相关的请求。SIGTERM 则是一个更加通用的、也更加优雅地退出信号。为了发出这个信号我们需要使用 kill命令, 它的语法是: kill -TERM <PID>

Ctrl+C : SIGINT

Ctrl+\ : SIGQUIT

Ctrl+Z : SIGTSTOP (信号暂停)

fg / bg : 恢复暂停的job于前台/后台

image-20221124213604608

jobs : 列出当前终端会话中尚未完成的全部任务

pgrep : 模糊搜索任务的PID

$! : 最近的一个任务

image-20221124213155164

kill
kill -TERM[-STOP/INT/QUIT] <PID>

2.终端多路复用(Terminal Multiplexe)

- sessions会话

  • tmux 开始一个新的会话
  • tmux new -s NAME 以指定名称开始一个新的会话
  • tmux ls 列出当前所有会话
  • tmux 中输入 <C-b> d ,将当前会话分离
  • tmux a 重新连接最后一个会话。您也可以通过 -t 来指定具体的会话

- windows窗口

  • <C-b> c 创建一个新的窗口,使用 <C-d>关闭
  • <C-b> N 跳转到第 N 个窗口,注意每个窗口都是有编号的
  • <C-b> p 切换到前一个窗口
  • <C-b> n 切换到下一个窗口
  • <C-b> , 重命名当前窗口
  • <C-b> w 列出当前所有窗口

- panes面板

  • <C-b> " 水平分割
  • <C-b> % 垂直分割
  • <C-b> <方向> 切换到指定方向的面板,<方向> 指的是键盘上的方向键
  • <C-b> z 切换当前面板的缩放
  • <C-b> [ 开始往回卷动屏幕。您可以按下<C-space>来开始选择(上下左右),<Alt+w复制选中的部分;<C-b> } 粘贴
  • <C-b> <空格> 在不同的面板排布间切换
  • <C-b> <C-arrow> 界面移动1行
  • <C-b> <Alt-arrow> 界面移动5行
  • <C-b> x 销毁面板
  • <C-b> t 显示时钟

3.别名

alias alias_name="command_to_alias arg1 arg2"

 创建常用命令的缩写
alias ll="ls -lh"

# 能够少输入很多
alias gs="git status"
alias gc="git commit"
alias v="vim"

# 手误打错命令也没关系
alias sl=ls

# 重新定义一些命令行的默认行为
alias mv="mv -i"           # -i prompts before overwrite
alias mkdir="mkdir -p"     # -p make parent dirs as needed
alias df="df -h"           # -h prints human readable format

# 别名可以组合使用
alias la="ls -A"
alias lla="la -l"

# 在忽略某个别名
\ls
# 或者禁用别名
unalias la

# 获取别名的定义
alias ll
# 会打印 ll='ls -lh'

4.远程连接

生成秘钥

ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519

验证: ssh-keygen -y -f /path/to/key

基于秘钥的认证机制

cat .ssh/id_ed25519 | ssh foobar@remote 'cat >> ~/.ssh/authorized_keys'

或者

ssh-copy-id -i .ssh/id_ed25519.pub foobar@remote

复制文件

  • ssh+tee, 最简单的方法是执行 ssh 命令,然后通过这样的方法利用标准输入实现 cat localfile | ssh remote_server tee serverfile。回忆一下,tee 命令会将标准输出写入到一个文件;
  • scp :当需要拷贝大量的文件或目录时,使用scp 命令则更加方便,因为它可以方便的遍历相关路径。语法如下:scp path/to/local_file remote_host:path/to/remote_file
  • rsyncscp 进行了改进,它可以检测本地和远端的文件以防止重复拷贝。它还可以提供一些诸如符号连接、权限管理等精心打磨的功能。甚至还可以基于 --partial标记实现断点续传。rsync 的语法和scp类似;

SSH配置

~/.ssh/config

Host vm
    User foobar
    HostName 172.16.174.141
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    LocalForward 9999 localhost:8888

# 在配置文件中也可以使用通配符
Host *.mit.edu
    User foobaz

其他配置

bash - ~/.bashrc, ~/.bash_profile
git - ~/.gitconfig
vim - ~/.vimrc 和 ~/.vim 目录
ssh - ~/.ssh/config
tmux - ~/.tmux.conf

Lecture6: 版本控制(Git)

  • 更改全局的branch_name : git config --global init.defaultBranch <name>
  • 更改当前仓库的分支名: git branch -m <name>

操作

基础

  • git help <command>: 获取 git 命令的帮助信息
  • git init: 创建一个新的 git 仓库,其数据会存放在一个名为 .git 的目录下
  • git status: 显示当前的仓库状态
  • git add <filename>: 添加文件到暂存区
  • git commit: 创建一个新的提交
  • git log: 显示历史日志
  • git log --all --graph --decorate: 可视化历史记录(有向无环图)
  • git diff <filename>: 显示与暂存区文件的差异
  • git diff <revision> <filename>: 显示某个文件两个版本之间的差异
  • git checkout <revision>: 更新 HEAD 和目前的分支

分支和合并

  • git branch: 显示分支
  • git branch <name>: 创建分支
  • git checkout -b <name>: 创建分支并切换到该分支
    • 相当于 git branch <name>; git checkout <name>
  • git merge <revision>: 合并到当前分支
  • git mergetool: 使用工具来处理合并冲突
  • git rebase: 将一系列补丁变基(rebase)为新的基线

远端操作

  • git remote: 列出远端
  • git remote add <name> <url>: 添加一个远端
  • git push <remote> <local branch>:<remote branch>: 将对象传送至远端并更新远端引用
  • git branch --set-upstream-to=<remote>/<remote branch>: 创建本地和远端分支的关联关系
  • git fetch: 从远端获取对象/索引
  • git pull: 相当于 git fetch; git merge
  • git clone: 从远端下载仓库

撤销

  • git commit --amend: 编辑提交的内容或信息
  • git reset HEAD <file>: 恢复暂存的文件
  • git checkout -- <file>: 丢弃修改
  • git restore: git2.32版本后取代git reset 进行许多撤销操作

Git 高级操作

  • git config: Git 是一个 高度可定制的 工具
  • git clone --depth=1: 浅克隆(shallow clone),不包括完整的版本历史信息
  • git add -p: 交互式暂存
  • git rebase -i: 交互式变基
  • git blame: 查看最后修改某行的人
  • git stash: 暂时移除工作目录下的修改内容
  • git bisect: 通过二分查找搜索历史记录
  • .gitignore: 指定 故意不追踪的文件

Lecture7: 调试及性能分析

调试代码

打印调试法与日志

第三方日志系统

journalctl --since "1m ago"

调试器

ipdb

  • install: pip install ipdb
  • start: python -m ipdb file.py
  • use:
    • l(ist) - 显示当前行附近的11行或继续执行之前的显示;
    • s(tep) - 执行当前行,并在第一个可能的地方停止;
    • n(ext) - 继续执行直到当前函数的下一条语句或者 return 语句;
    • b(reak) - 设置断点(基于传入的参数);
    • p(rint) - 在当前上下文对表达式求值并打印结果。还有一个命令是pp ,它使用 pprint 打印;
      • p [arr_name] - 返回指定参数的值
      • p locals() - 返回所有值得字典
    • r(eturn) - 继续执行直到当前函数返回;
    • q(uit) - 退出调试器。
    • c(ontinue) - 继续执行
    • Enter - 重复上一条命令

更底层的编程语言的调试器gdb

专门工具

系统调用: strace

网络数据包: tcpdump Wireshark

web

静态分析

静态分析

pyflakes

image-20221202232923986

mypy : 可以对代码进行类型检查

image-20221202233033197

shell - shellcheck

文本 - writegood

code linting

ale

在 vim 中,有 alesyntastic 可以帮助您做同样的事情。 在 Python 中, pylintpep8 是两种用于进行风格检查的工具,而 bandit 工具则用于检查安全相关的问题。

自动格式化

black

用于 Python 的 black、用于 Go 语言的 gofmt、用于 Rust 的 rustfmt 或是用于 JavaScript, HTML 和 CSS 的 prettier

性能分析

计时

  • print(time.time() - start)
  • time [do]

性能分析工具(profilers)

cpu
  • 追踪分析器(tracing): 记录程序的每一次函数调用

  • 采样分析器(sampling): 周期性的监测(通常为每毫秒)您的程序并记录程序堆栈

  • cProfile: 显示每次函数调用的时间

    • python -m cProfile -s tottime grep.py 1000 '^(import|\s*def)[^,]*$' *.py
  • line_profiler: 基于行来显示时间

    • kernprof -l -v a.py
内存

事件分析

perf

  • perf list - 列出可以被 pref 追踪的事件;
  • perf stat COMMAND ARG1 ARG2 - 收集与某个进程或指令相关的事件;
  • perf record COMMAND ARG1 ARG2 - 记录命令执行的采样信息并将统计数据储存在perf.data中;
  • perf report - 格式化并打印 perf.data 中的数据。

资源监控

  • 通用监控 - 最流行的工具要数 htop,了,它是 top的改进版。htop 可以显示当前运行进程的多种统计信息。htop 有很多选项和快捷键,常见的有:<F6> 进程排序、 t 显示树状结构和 h 打开或折叠线程。 还可以留意一下 glances ,它的实现类似但是用户界面更好。如果需要合并测量全部的进程, dstat 是也是一个非常好用的工具,它可以实时地计算不同子系统资源的度量数据,例如 I/O、网络、 CPU 利用率、上下文切换等等;
  • I/O 操作 - iotop 可以显示实时 I/O 占用信息而且可以非常方便地检查某个进程是否正在执行大量的磁盘读写操作;
  • 磁盘使用 - df 可以显示每个分区的信息,而 du 则可以显示当前目录下每个文件的磁盘使用情况( disk usage)。-h 选项可以使命令以对人类(human)更加友好的格式显示数据;ncdu是一个交互性更好的 du ,它可以让您在不同目录下导航、删除文件和文件夹;
  • 内存使用 - free 可以显示系统当前空闲的内存。内存也可以使用 htop 这样的工具来显示;
  • 打开文件 - lsof 可以列出被进程打开的文件信息。 当我们需要查看某个文件是被哪个进程打开的时候,这个命令非常有用;
  • 网络连接和配置 - ss 能帮助我们监控网络包的收发情况以及网络接口的显示信息。ss 常见的一个使用场景是找到端口被进程占用的信息。如果要显示路由、网络设备和接口信息,您可以使用 ip 命令。注意,netstatifconfig 这两个命令已经被前面那些工具所代替了。
  • 网络使用 - nethogsiftop 是非常好的用于对网络占用进行监控的交互式命令行工具。

专用工具

hyperfine

Lecture8: 元编程(Metaprogramming)*

Lecture9: 安全和密码学(Security and Cryptography)*

熵(Entropy)

熵的单位是 比特 = l o g 2 p r o b i l i t y log_2{probility} log2probility

散列函数

hash(value: array<byte>) -> vector<byte, N> (N对于该函数固定)

特性

  • 确定性:对于不变的输入永远有相同的输出。
  • 不可逆性:对于hash(m) = h,难以通过已知的输出h来计算出原始输入m
  • 目标碰撞抵抗性/弱无碰撞:对于一个给定输入m_1,难以找到m_2 != m_1hash(m_1) = hash(m_2)
  • 碰撞抵抗性/强无碰撞:难以找到一组满足hash(m_1) = hash(m_2)的输入m_1, m_2(该性质严格强于目标碰撞抵抗性)。

Lecture10: 大杂烩(Potpourri)

修改键位映射

守护进程(daemon)

查看所有守护进程: systemctl status


  1. shellcheck ↩︎

  2. tmux ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bayyys

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值