Shell 学习笔记 0x03
1. 一些很酷的文本格式化工具
1.1. nl
添加行号:
1 | echo 'foo\nbar\n\nwhat\nthe\n\nfuck\n?!' |
-ba: body numbering ,设置为 all ,为所有行(包括空行)添加行号-nrz: number format ,设置为 right justified with leading zeros ,右对齐并用0填充-w3: number width ,设置为 3-s' ': number separator ,设置为,行号与正文之间放一个空格
1.2. fold
限制行宽,比如 clang-format 好像是限制一行最多 80 个字符,可以像这样实现:
1 | fold -w80 -s < main.cc > main.folded.cc |
1.3. fmt
更高级的格式化工具,刚才用 fold 处理 C++ 代码可能会产生问题,比如一行注释超过了 80 宽, fold 会直接把超过的部分放在新的一行,但不会加上 // ,这时 fmt 可以有更好的实现:
1 | fmt -w80 -p'// ' main.cc > main.fmted.cc |
1.4. printf
跟 C 的差不多:
1 | printf 'He%dlo W%drld\n' 1 0 |
2. Bye World
为啥都是 Hello World 呢,一般输出这句话程序不就退出了吗?那不应该输出 Bye World 吗?
1 |
|
第一行 #!/bin/sh 叫 shebang , #! 后面接这个脚本的解释器, /bin/sh 表示系统默认的 Shell ,在我的 ArchLinux 下是 /bin/bash 的 symbolic link ,在我的 Debian 下是 /bin/dash 的 symbolic link ,所以我觉得写 #!/bin/sh 更加通用
2.1. PATH
我给 ~/.local/bin 放进了我的 PATH 里了,修改了 rc 文件后可以用 built-in command ./source 来重新加载:
1 | . .zshrc |
2.2. 折行
如果一行写不下可以用 line continuation (行继续符)来折行:
1 |
|
使用 "" 包围的字符串可以包含换行:
1 |
|
2.3. 变量
跟 Python 一样, Shell 也可以随便声明一个变量:
1 |
|
Shell 在执行 echo $foo 时会先展开 $foo 为 "bar" ,实际上执行的是 echo "bar" ,如果执行时某个变量没有定义,可能会导致一些问题,比如:
1 |
|
会导致 Shell 实际执行 mv foo ,少了一个参数, mv 会报错。可以用 {} 包围变量名:
1 |
|
实际上执行的指令则为 mv foo bar.dir
Shell 中为变量赋值的
=两边不能有空格,因为空格默认被视为分隔符,foo = bar会被视为执行指令foo并带上参数=和bar
2.4. Here Document
1 |
|
脚本会输出
1 | line 1 |
<< 后面接一个语句(可以进行求值),这个语句的结果将会作为末尾的标志,换行后可以输入任意内容,直至末尾的标志单独地出现在一行(开头和结尾都没有多余的空格),比如上面的就用 EOF 作为末尾的标志,两个 EOF 之间的内容就会被放进 cat 的 stdin 里(可以通过 n<<
再比如:
1 |
|
会输出:
1 | 114514 |
使用 <<- 可以忽略后面每行用于格式化的 \t (只忽略 \t ,其他空字符不算):
1 | cat <<- EOF |
输出:
1 | foo |
2.5. 函数
1 | function foo { |
都可以是函数的定义,可以像这样直接调用:
1 | foo |
或者展开:
1 | echo "$(foo) $(bar) $(baf)" |
2.6. 局部变量
1 |
|
输出:
1 |
|