6.NULL-The-Missing-Semester-of-Your-CS-Education
The Missing Semester of Your CS Education
该课程主要是教如何更高效的使用命令行、编辑器、Git 等工具。
Lecture 1 - Course overview + the shell
Notes
- > 将一个命令/程序的输出流重定向到一个 文件, < 相反。>> 和 << 用做追加
- 管道符
|与 > 不同的是,目标可以是 命令/程序 - 单引号:所见即所得
- 双引号:所见非所得,它会先把变量解析之后,再输出
Exercises
这一节练习比较简单,所以其他的省略。
- Write the following into that file, one line at a time:The first line might be tricky to get working. It’s helpful to know that # starts a comment in Bash, and ! has a special meaning even within double-quoted (“) strings. Bash treats single-quoted strings (‘) differently: they will do the trick in this case. See the Bash quoting manual page for more information.
1
2#!/bin/bash
curl --head --silent https://missing.csail.mit.edu1
2echo '#!/bin/bash' >> semester
echo curl --head --silent https://missing.csail.mit.edu >> semester - Use | and > to write the “last modified” date output by semester into a file called last-modified.txt in your home directory.
1
./semester | grep last-modified | cut -d " " -f 2- > last-modified.txt
Lecture 2 - Shell Tools and Scripting
Notes
- To assign variables in bash, use the syntax foo=bar and access the value of the variable with $foo. Note that foo = bar will not work since it is interpreted as calling the foo program with arguments = and bar. In general, in shell scripts the space character will perform argument splitting. This behavior can be confusing to use at first, so always check for that.
$_上条命令的最后一个参数1
2
3# e.g.
$mkdir test
$cd $_$?上条命令的错误代码(返回值)$0脚本名字,$1到$9为 bash 脚本的第一个到第九个参数$?错误代码, 0正常1错误- 花括号{} - 当你有一系列的指令,其中包含一段公共子串时,可以用花括号来自动展开这些命令。这在批量移动或转换文件时非常方便。
1
2
3
4
5
6
7
8
9
10# e.g.
$mkdir {foo,bar}
$mkdir {foo,bar}/{a,b,c}
$mkdir foo/x bar/y
$diff {foo,bar}
Common subdirectories: foo/a and bar/a
Common subdirectories: foo/b and bar/b
Common subdirectories: foo/c and bar/c
Only in foo: x
Only in bar: y - 当您通过 $( ls ) 这样的方式来执行 ls 这个命令时,它的输出结果会替换掉 $( ls ) 。例如,如果执行 for file in $(ls) ,shell首先将调用ls ,然后遍历得到的这些返回值。
- <() 进程替换(process substitution), <( ls ) 会执行 ls 并将结果输出到一个临时文件中,并将 <( ls ) 替换成临时文件名。这在我们希望返回值 通过文件而不是STDIN传递 时很有用。例如, diff <(ls foo) <(ls bar) 会显示文件夹 foo 和 bar 中文件的区别。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# e.g.
$cat <(ls foo) <(ls bar)
a
b
c
x
a
b
c
y
$diff <(ls bar) <(ls foo)
4c4
< y
---
> x - 通配符 - 当你想要利用通配符进行匹配时,你可以分别使用 ? 和 * 来匹配一个或任意个字符。例如,对于文件foo, foo1, foo2, foo10 和 bar, rm foo?这条命令会删除foo1 和 foo2 ,而rm foo* 则会删除除了bar之外的所有文件。
- find
1
2# e.g. 删除全部扩展名为.tmp 的文件
find . -name '*.tmp' -exec rm {} \;
Exercises
Write bash functions marco and polo that do the following. Whenever you execute marco the current working directory should be saved in some manner, then when you execute polo, no matter what directory you are in, polo should cd you back to the directory where you executed marco. For ease of debugging you can write the code in a file marco.sh and (re)load the definitions to your shell by executing source marco.sh.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing cat marco.sh
#!/bin/bash
marco(){
pwd > /tmp/missing/save-path.log
}
polo(){
p=$(cat /tmp/missing/save-path.log)
cd "$p"
}
⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing cd /usr/local/dev
⚡ root@izwz9bpgwmtcoix1llcjwqz /usr/local/dev source /tmp/missing/marco.sh
⚡ root@izwz9bpgwmtcoix1llcjwqz /usr/local/dev marco
⚡ root@izwz9bpgwmtcoix1llcjwqz /usr/local/dev cat /tmp/missing/save-path.log
/usr/local/dev
⚡ root@izwz9bpgwmtcoix1llcjwqz /usr/local/dev cd /
⚡ root@izwz9bpgwmtcoix1llcjwqz / polo
⚡ root@izwz9bpgwmtcoix1llcjwqz /usr/local/devSay you have a command that fails rarely. In order to debug it you need to capture its output but it can be time consuming to get a failure run. Write a bash script that runs the following script until it fails and captures its standard output and error streams to files and prints everything at the end. Bonus points if you can also report how many runs it took for the script to fail.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 cat call.sh
#!/usr/bin/env bash
count=1
while true;do
./mock &>> out.log
if [[ $? -ne 0 ]]; then
cat out.log
echo "$count"
break
fi
((count++))
done
⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 ./call.sh
119
⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 cat out.log
...
Everything went according to plan
Everything went according to plan
Everything went according to plan
Something went wrong
The error was using magic numbersYour task is to write a command that recursively finds all HTML files in the folder and makes a zip with them. Note that your command should work even if the files have spaces (hint: check -d flag for xargs).
1
2
3
4
5
6⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 mkdir {a,b}
⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 touch {a,b}/{1,2.html,3.html}
⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 touch {a,b}/{4\ 4.html,5\ 5.html}
⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 find . -name "*.html" -print0 | xargs -0 zip -r 1.zip
# or
⚡ root@izwz9bpgwmtcoix1llcjwqz /tmp/missing/lecture-2 find . -type f -name "*.html" | xargs -d '\n' tar -cvzf html.zip
Lecture 3 - command-lineShell Tools and Scripting
Notes
Exercises
Job control
2. …
However, this strategy will fail if we start in a different bash session, since wait only works for child processes. One feature we did not discuss in the notes is that the kill command’s exit status will be zero on success and nonzero otherwise. kill -0 does not send a signal but will give a nonzero exit status if the process does not exist. Write a bash function called pidwait that takes a pid and waits until the given process completes. You should use sleep to avoid wasting CPU unnecessarily.
1 | |
Dotfiles
5.Migrate all of your current tool configurations to your dotfiles repository.
1 | |