什么是 Shell?
Shell 的英文是壳,也就是我们俗称的命令行工具,由于我们无法和操作系统的核心(Kernel)直接交互,所以需要一层中转,这层就是 Shell。
一个命令有哪些要素构成?
- 可执行程序
- 参数
- 环境变量
- 工作目录
如果你执行某个命令与其他人的结果不一样,那么可能是这些要素的其中一些不同造成的。
程序是怎么获取到环境变量的?
当我们启动了一个程序,在操作系统中就是一个进程,如果这个进程启动了一个新的进程,比如我们通过终端运行 node,那么 node 程序则会拿到它的父进程的环境变量,所以如果我们在一个终端窗口,运行 export AAA=123,指定了一个临时变量,再启动其他程序,其他程序可以读取到这个变量,但是如果我们打开一个新的终端窗口,就拿不到这个变量了,因为环境变量和进程是绑定的。
参数有什么约定?
- 当使用一个横杠的时候,比如
-a,那么后面通常都是只跟一个字母,表示某个单词的缩写。不过大部分程序也支持接收例如-al这种表示-a和-l的组合。 - 当时使用二个横杠的时候,比如
--all,那么后面通常都是跟着一个单词。
参数中的单双引号有什么区别?
- 单引号包裹的字符,会被解析成纯字符,比如 “123A 就是纯字符,不会被解析成环境变量。
- 双引号包裹的字符,则会展开其中的变量。
- 如果你的值中包含引号,那么可以使用转义字符来包含引号。
参数中的通配符是由谁解析的?
假如我们执行 ls *,那 ls 程序收到的是一个 * 参数,还是一堆展开的当前文件名的多个参数?大多数情况下,shell 并不会处理我们的参数,但是像这种通配符的情况,shell 会自动解析,所以被执行的程序收到的是多个参数。这个确实可以理解,如果 shell 不解析的话,那么每个程序都得自己实现一遍解析通配符的逻辑。
>, >>, 1>, 2> 有什么区别?
标准输出和标准错误是进程的概念,所以每个语言都会支持,例如 echo 123 > test.txt,> 默认会把命令的标准输出重定向到下一条命令。>> 则表示追加。因为 > 等价于 1>,1 表示标准输出。如果我们希望获取标准错误,则使用 2> 或者是 2>> 这种方式。如果想要输出和错误都保留,则可以使用 echo 123 > test.txt 2>&1,2>&1 表示将标准错误重定向到标准输出。这里的顺序看上去确实有点迷惑,和 bash 脚本相关,暂时了解即可。