这门MIT课很实用地介绍了CS学习过程中实用的工具用法等等。🔗:课程网站。我把这其中平时会经常用到但是我不太会的部分按照课程专题Topic记录下来,可以随时查阅:
与各种图形界面相对应,纯文字的interface就叫作shell。我们以bash(Bourne Again SHell)为例来介绍shell的用法。
基础

参数写法:
比如一个名叫”My Photos”的文件夹名,可以写为:
- ‘My Photos’
 - “My Photos”
 - My\ Photos
 
PATH
shell在运行命令的时候会寻找相应的PATH,按照顺序优先选择对应的PATH:

文件权限

d:directory,表示是一个文件夹。- 剩下的权限三个字母一组,分别表示 the owner of the file(
missing),the owning group(users)和所有其他用户的权限。 r: read.对于目录,有read权限才能ls。w:write.包括move, delete, rename……x:execute. 对于目录,有execute权限才能cd。
streams
cat:cat指concatenate,it prints contents from its input stream to its output stream. 默认output是屏幕。<: rewrite input;>: rewrite output;>>: append to a file.
pipes
|:”chain” programs such that the output of one is the input of another.
进阶
从这些命令再进阶,就是写shell脚本啦!接下来以bash scripting为例:
变量
‼️bash脚本中的空格是用来分隔参数的,不要随便空格!比如,当你写foo = bar时表示foo是一个程序名(类似ls),=是传入foo程序的第一个参数,bar是传入foo程序的第二个参数。
‼️单引号和双引号完全不同!单引号表示的是string,双引号既能表示string,也能代入变量。
变量可以用$foo或者"$foo"表示。

写文件
将命令写到函数里,放在文件里:

执行:

参数
bash中有很多预留的参数,可以通过🔗Special Characters查看。比较实用的:
$0: name of the script.$1到$9:参数!!:last command,用法比如(sudo !!):
$_: last argument$?: return code of the previous command. 如果没有错误,return就是0。例子如下:在mcd.sh中没有foobar,所以return code是1。true的error code是0,false的error code是1。

布尔运算
分号隔绝了两个command,所以不管前一个命令是true和false,后面都一样执行。

command substitution
将命令执行的结果作为输入。比如:

process substitution
比如:

执行的效果就是concatenate ls和ls ..的命令结果。以<(ls)为例,讲解process substition做了什么:
- 执行
ls - 将
ls的结果写入一个temporary file - 将
<(ls)替换为temporary file的文件名 
一个综合例子

bash中的比较可以查看
man test,比如上面程序中的-ne。为了保证bash能和sh兼容,比较的时候用[[ ]]而不是[ ]。执行上述脚本:

globbing

Other scripts
🔗shellcheck。可以用来找出你的sh/bash脚本的错误。
Python script

Shell Tools
Finding how to use commands
man🔗TLDR pages. 比
man更具体,会有例子说明。
Finding files
find
-name是区分大小写的,-iname不区分大小写。
fd。可以用正则表达式,比find更简洁,直接fd PATTERN就行。🔗fdlocate。locate属于Unix System原生的设计,使用了一个数据库build index,在进行查找时更快,数据库更新需要updatedb。
Finding code
当比起文件,我们更在乎文件内容时,我们可以用grep。
grepgrep foobar mcd.sh grep -R foobar # C表示content, grep -C 5在查找返回时保留上下5行内容 grep -C 5 # v表示inverse,这里是反向查找,查找不包含pattern的内容 grep -v patternrg(ripgrep)🔗rg
跟
grep相比,有颜色显示,unicode支持,比grep更快。# 找到~/scratch下所有包含"important requests"的python文件 rg "important requests" -t py ~/scratch # 找到后要上下5行的context rg "important requests" -t py -C 5 ~/scratch # 找到所有不以#!(shebang line)开头的sh文件,-u表示不要忽略隐藏文件 rg -u --files-without-match "^#\!" -t sh # --stats会给出match的数据,有多少行match,多少文件match等等 rg "important request" -t py -C 5 --stats ~/scratch # -A指的是following lines rg foo -A 5ack🔗ack
ag🔗ag
Finding shell commands
在历史中找到自己曾经输入的命令。
history# 在zsh只能print部分history history # print所有history history l # 找到所有find命令 history l | grep findCRTL+Rfzf(fuzzy finder)🔗fzf。跟
grep相比,你不需要写正则表达式,这种模糊查找很简单易用,可以跟CRTL+Rbinding,操作简捷。cat example.sh | fzfhistory-based autosuggestions
可以进行命令自动补全,在zsh上设置:🔗zsh-autosuggestions
Directory Navigation
# list some directory structure
ls -R
# 比-R更友好
tree
broot
# more os like, interactive input
nnn
我们可以用cd切换目录,但是也可以选择更快捷的方式去我们经常去的目录下。
文档信息
- 本文作者:weownthenight
 - 本文链接:https://weownthenight.github.io/2022/09/01/The-Missing-Semester-of-CS-The-Shell/
 - 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)