add blog
This commit is contained in:
409
content/blog/linux-guide.md
Normal file
409
content/blog/linux-guide.md
Normal file
@@ -0,0 +1,409 @@
|
||||
---
|
||||
title: 'Linux 教程新手篇(草稿)'
|
||||
date: 2024-11-16T22:13:37+08:00
|
||||
---
|
||||
|
||||
在做实验,需要每五分钟去调整一下仪器,但中间的五分钟有点无事可做。
|
||||
所以来写一下这个东西得了。
|
||||
|
||||
原本是想要写个给同专业的同学看的教程,写了一点觉得,诶,我为啥不写成更通用的教程呢。
|
||||
于是就这样做吧。
|
||||
|
||||
## 顶层设计
|
||||
|
||||
我的想法是这样的:按照两个部分去写,一个新手篇,一个进阶篇。
|
||||
不管哪个部分,内容都不会限制于 Linux,甚至 Linux 的内容可能只占一半。
|
||||
其实很多人并不是不会用 Linux 而是对缺少对操作系统的一般认识,
|
||||
就像看到自己电脑有 C D E F 盘,就以为电脑里真的插了四个硬盘一样。
|
||||
另一个常见的误区就是不区分内存和外存。类似此类的问题。
|
||||
要真的只是某个 Linux 上的问题不会,反而还都是少见的。
|
||||
|
||||
暂时的计划是这样的,新手篇的内容包含:
|
||||
* 什么是 shell?(和 windows 的桌面一个作用,只是变成了敲命令)
|
||||
* shell 里命令的格式是怎样的?(第一个是要执行的程序,之后的是参数)
|
||||
* 常用的几个命令。
|
||||
说白了就是围绕 bash 介绍一些基础用法。
|
||||
这其实是相当繁琐的事情,但又是很基础的,不得不介绍,新手接触 Linux 的话也不可能绕过。
|
||||
|
||||
进阶篇的内容会多一些杂一些,包括:
|
||||
* 冯诺依曼架构(计算机的硬件组成,至少把内存和外存分清楚吧)
|
||||
* 操作系统的结构(内核和用户态程序的区别)
|
||||
* 分区、文件系统、挂载,这些概念是指什么;linux常见的几个文件夹里放什么。
|
||||
* 程序和进程间通信(环境变量,信号,输入输出,返回值)
|
||||
* shell 中一些内置命令,以及重定向、通配符等。
|
||||
* 常用的工具(shell 中常用的外置命令)。
|
||||
* 用户、文件所有者和权限。
|
||||
* 网络协议,NAT。
|
||||
* 编程时常用的概念(编译、链接、解释器等)。
|
||||
|
||||
在这之后就区分“专业”了,例如做科学计算的话,需要了解:
|
||||
* 常用的并行计算协议(MPI,OpenMP,CUDA,OpenCL,SYCL)。这里其实我也缺一些知识,我需要自己先把自己的疑惑解决了再写。
|
||||
* 队列系统。但是我已经写过了。
|
||||
|
||||
当然也可以写一些其它的。但这些要么已经有人写过了写得很好我受益匪浅,我觉得不需要我来写(例如 nix),要么我自己也不熟(例如 docker)。
|
||||
总之,写个屁。
|
||||
|
||||
我想要达成的目标是这样的:
|
||||
* 对于普通用户:
|
||||
* 读完新手篇,就可以着手做计算了。
|
||||
* 读完进阶篇,就大致知道自己遇到常见的错误时如何排查,或者如何向别人描述问题了。
|
||||
* 对于管理员:
|
||||
* 全读完,就可以开始学习怎么搭服务器了(遇到问题时,知道去哪里找答案了)。
|
||||
|
||||
不只是做计算,如果有想自己折腾 Linux 的,这也算是一个比较好的入门;但我会侧重于前者,主要是后者的话,场景太杂,我根本不知道该写啥。
|
||||
|
||||
所以说应该会写四个部分:
|
||||
* 速查篇,列个表格,满足某些人“我要一口吞个大象”的心态,他吞不下是他的问题,我给他把大象放到这里。
|
||||
* 新手篇,口语化地带领读者实践一圈。
|
||||
* 进阶篇,讲基础的、常见的、重要的、但是又往往被忽略的概念,为了给进一步向前走做准备。
|
||||
* 专业篇,指科学计算,这一部分更偏向于我自己的整理而不是科普给别人。
|
||||
|
||||
## 那就开始吧
|
||||
|
||||
下面是新手篇。
|
||||
|
||||
### 那个黑框框里是什么?
|
||||
|
||||
先考虑这个问题:在 Windows 电脑上,如何删除一个文件?步骤是这样的:
|
||||
1. 启动**资源管理器**(就是“我的电脑”或者“此计算机”)。
|
||||
2. 打开你要删除的文件所在的文件夹。
|
||||
3. 右键点击文件,选择删除。
|
||||
在这个过程中,“资源管理器”或者“exploer.exe”承担了这样一个“传话筒”的角色:
|
||||
它接受你下达的指令(打开某个文件夹,删除某个文件,等),并将这个指令传达给系统中那些更底层的程序(即内核)去执行。
|
||||
|
||||
通过 PuTTY 或者别的什么程序连接到服务器后打开的那个黑框框,就是 Linux 系统中的“资源管理器”[^2],它的名字叫“bash”[^3]。
|
||||
它的作用与 Windows 的资源管理器是一样的:你可以给他传达删除某个文件、启动某个程序等指令,它就会把这个指令传达给系统的更底层去实际执行。
|
||||
学习 Linux 的第一步,就是学习如何给 bash 下达指令,例如打开某个文件夹、删除某个文件、启动某个程序等。
|
||||
至于其中的细节(例如 bash 是如何与内核交互的,为了删除一个文件内核又需要做什么),暂时不需要关心。
|
||||
|
||||
类似于 Windows 的资源管理器或 bash 这样的程序被称为“shell”,也就是“壳”,
|
||||
这是指它把系统中复杂的细节包装了起来,让用户可以简单地进行删除文件、打开文件夹等操作,大多情况下不用关心细节。
|
||||
|
||||
### 几个常见的命令
|
||||
|
||||
学习英语的第一步并不是钻研语法,而是学习最常用的几句话大致怎么说。学习 bash 也是一样的。
|
||||
下面是几个最常用的命令,你可以跟着操作一遍,就大致知道这些命令该怎么用了,同时也可以理解 Linux 上一些基本的概念。
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
如果你是在学校超算(jykang)上跟着操作,那么一定要小心,每一次回车前都要仔细检查输入的命令是否正确,千万不要误操作。
|
||||
{{< /callout >}}
|
||||
|
||||
#### `pwd`
|
||||
|
||||
在 Windows 的资源管理器中,可以在窗口上部、标题栏下方的地址栏中看到现在打开的是哪个文件夹(称为当前的“工作目录”);
|
||||
而在 bash 中,可以使用 `pwd` 命令查看工作目录的路径(`pwd` 是“print working directory”的缩写):
|
||||
```bash
|
||||
pwd
|
||||
```
|
||||
将 `pwd` 输入到黑框框中,然后按回车键,它就会输出一行文字,告诉你现在在哪个文件夹下。例如,它输出的结果可能是:
|
||||
```
|
||||
/home/chn
|
||||
```
|
||||
这表示你现在打开的是“**根目录**”下的 `home` 文件夹下的 `chn` 文件夹。
|
||||
|
||||
要解释“根目录”的意思,需要先提到一个 Linux 与 Windows 的不同之处:
|
||||
Windows 中往往逻辑上有多个“磁盘”(C 盘、D 盘、E 盘等),而 Linux 中**逻辑上**只有一个“磁盘”,这个“磁盘”就是所谓的“根目录”。
|
||||
当然,这个“根目录”中的内容完全可能实际是分布在多个硬盘上存储的(例如,某几个文件夹在一个硬盘上,另外几个文件夹在另一个硬盘上),
|
||||
但这些细节初学者并不需要关心,这些文件实际上存储在哪里对初学者来说操作起来完全没有区别。
|
||||
|
||||
你还会发现另外一个区别:在 Windows 中,文件夹之间的分隔符是反斜杠 `\`,而在 Linux 中,文件夹之间的分隔符是斜杠 `/`。
|
||||
|
||||
还有第三个重要的区别你可能没有发现:
|
||||
在 Windows 中,文件和文件夹名字是不区分大小写的,也就是说无法在同一个文件夹下新建 `aaa.txt` 和 `AAA.txt` 两个文件;
|
||||
而 Linux 中文件和文件夹名是区分大小写的,`aaa.txt` 和 `AAA.txt` 完全可以同时存在。
|
||||
不仅仅是文件名,整个 Windows 的习惯都是不区分大小写的,而整个 Linux 的习惯则都是区分大小写的。
|
||||
总之,我们之后学习的所有命令、各种参数等,它们都是区分大小写的;
|
||||
如果你在哪里看到过某某命令不区分大小写的说法,那大概率是 Windows 的特色,不能不经确认套用到 Linux 上。
|
||||
|
||||
#### `ls`
|
||||
|
||||
使用 `ls` 命令(“list”的缩写)列出当前目录下,名字不以 `.` 开头的文件和文件夹(也就是不隐藏的文件和文件夹):
|
||||
```bash
|
||||
ls
|
||||
```
|
||||
|
||||
在 Windows 上,一个文件或者文件夹是否是隐藏的,是它的一个属性(右击-属性中,可以修改);
|
||||
但在 Linux 上,通常直接把名字以 `.` 开头的文件或文件夹称为“隐藏文件”或“隐藏文件夹”,并通常用来存放程序的设置等用户平时不需要修改的内容。
|
||||
隐藏的文件与不隐藏的文件本质上并没有什么不同,这只是一种习惯性的用法。
|
||||
|
||||
要列出当前目录中所有的文件和文件夹(包括隐藏的),可以使用 `ls -a` 命令(“a”是“all”的缩写):
|
||||
```bash
|
||||
ls -a
|
||||
```
|
||||
你一定可以看到两个特殊的文件夹:一个名字叫 `.`,令一个叫 `..`。我稍后会介绍它们是什么。
|
||||
|
||||
要列出别的地方的文件夹里的内容(而不是当前文件夹),可以在 `ls` 命令后面加上这个文件夹的路径,例如:
|
||||
```bash
|
||||
ls /
|
||||
```
|
||||
这会列出根目录下的文件和文件夹(不包括隐藏的)。
|
||||
```bash
|
||||
ls /home/chn
|
||||
```
|
||||
这会列出 `home` 文件夹下的 `chn` 文件夹中的文件和文件夹(不包括隐藏的)。
|
||||
当然,如果你没有权限看这个文件夹里的内容的话,这个命令就会报错,但也不会有什么坏处,也不会影响之后的命令。
|
||||
|
||||
你可以按照自己的兴趣,随意列出几个文件夹的内容,探索一下服务器上有什么东西。不会把服务器搞坏的,不用担心。
|
||||
也可以将 `ls` 列出来的东西与 WinSCP 对照者看一下,确认它们是一样的[^4]。
|
||||
|
||||
{{< callout type="info" >}}
|
||||
如果你尝试列出 `/nix/store` 或者 `.node_modules` 的文件夹的内容,你的 shell 可能会卡死,这只是因为里面的文件太多了。
|
||||
你可以耐心等待它列完,也可以按 `Ctrl + C` 来终止这个命令,实在不行就重启 PuTTY。
|
||||
{{< /callout >}}
|
||||
|
||||
#### `mkdir`
|
||||
|
||||
使用 `mkdir` 命令(“make directory”的缩写)在当前目录下创建一个新的文件夹:
|
||||
```bash
|
||||
mkdir test
|
||||
```
|
||||
这样就在当前目录下创建了一个名为 `test` 的文件夹。
|
||||
|
||||
#### `cd`
|
||||
|
||||
使用 `cd` 命令(“change directory”的缩写)切换当前目录(也就是,打开别的文件夹):
|
||||
```bash
|
||||
cd test
|
||||
```
|
||||
这样就进入了当前目录下的 `test` 文件夹。
|
||||
|
||||
如果要返回上一级目录,可以使用 `cd ..` 命令:
|
||||
```bash
|
||||
cd ..
|
||||
```
|
||||
|
||||
还记得前面提到的 `.` 和 `..` 这两个特殊的文件夹吗?其实 `..` 就是指上一层文件夹,而 `.` 就是指同一层文件夹。
|
||||
例如,下面几个目录的写法,它们之间是完全等价的:
|
||||
```bash
|
||||
/home/chn
|
||||
/home/chn/.
|
||||
/home/chn/./././././.
|
||||
/home/../home/chn
|
||||
/home/chn/../../home/chn
|
||||
/home/././chn/.././chn
|
||||
```
|
||||
|
||||
目前为止,很多命令都需要用到文件或文件夹的路径。
|
||||
实际上,文件或者文件夹的路径有两种写法,大多数情况下(包括基础篇中提到的所有命令但不仅限于),两种写法都可以,完全等价:
|
||||
* 直接写当前目录下的文件或文件夹的名字,例如 `cd test` 或者 `cd ./test` 或者 `cd ./test/../test` 等,这种写法称为相对路径;
|
||||
* 写完整的路径(以 `/` 开头的路径),例如 `cd /home/chn/test`,这种写法称为绝对路径。
|
||||
但也存在一些例外,其中一个重要的例外在基础篇的最后会提到。
|
||||
|
||||
#### `echo`
|
||||
|
||||
使用 `echo` 命令输出一行文字:
|
||||
```bash
|
||||
echo Hello
|
||||
```
|
||||
这样就输出了一行 `Hello`。——这有什么用呢?
|
||||
|
||||
可以使用下面这个命令,在当前目录下创建一个名为 `file.txt` 的文件,并在这个文件中写入一行 `Hello`
|
||||
(如果这个文件之前已经存在,其中的内容会被覆盖):
|
||||
```bash
|
||||
echo Hello > file.txt
|
||||
```
|
||||
如果你想在这个文件中追加一行 `World`(之前的内容不会被覆盖),可以使用下面这个命令:
|
||||
```bash
|
||||
echo World >> file.txt
|
||||
```
|
||||
这里的 `>` 和 `>>` 是两个特殊的符号,被称为“重定向符号”,
|
||||
它表示把之前的命令的标准输出(也就是,原本会输出到屏幕上的内容[^5])重定向到某个文件中。
|
||||
`>` 表示覆盖,`>>` 表示追加。
|
||||
它们的用法不仅限于 `echo` 命令,而是可以用在任意的命令上,例如 `ls > file.txt` 就会把 `ls` 命令的输出重定向到 `file.txt` 文件中。
|
||||
|
||||
#### `cat`
|
||||
|
||||
使用 `cat` 命令(“meow meow meow”的缩写[^6])查看一个文件的内容:
|
||||
```bash
|
||||
cat file.txt
|
||||
```
|
||||
|
||||
你当然可以“活学活用”,把 `cat` 命令的输出重定向到另一个文件中,这样就变相实现了文件的复制:
|
||||
```bash
|
||||
cat file.txt > file2.txt
|
||||
```
|
||||
|
||||
类似于这样的“活学活用”在 Linux 中其实比比皆是。就像一篇光鲜亮丽的 sci 论文背后总是充满了科研现实的苟且。
|
||||
|
||||
#### `cp`
|
||||
|
||||
这个才是正经用来复制文件的命令(`copy` 的缩写):
|
||||
```bash
|
||||
cp file.txt file2.txt
|
||||
```
|
||||
|
||||
如果要复制的是文件夹,需要加上 `-r` 参数(“r”是“recursive”的缩写[^7]):
|
||||
```bash
|
||||
cp -r test test2
|
||||
```
|
||||
|
||||
#### `rm`
|
||||
|
||||
使用 `rm` 命令(“remove”的缩写)删除一个文件:
|
||||
```bash
|
||||
rm file.txt
|
||||
```
|
||||
这样就删除了当前目录下的 `file.txt` 文件。
|
||||
|
||||
要删除文件夹,需要加上 `-r` 参数(与 `rm` 相同):
|
||||
```bash
|
||||
rm -r test
|
||||
```
|
||||
这样就删除了当前目录下的 `test` 文件夹。
|
||||
|
||||
### bash 的基本语法
|
||||
|
||||
#### 按行分割
|
||||
|
||||
英语分为一个个句子,以句号作为结尾;输入给 bash 的指令是一条一条的,通常以换行作为结尾。
|
||||
例如,输入下面的命令:
|
||||
```bash
|
||||
cd test
|
||||
rm file.txt
|
||||
cd ..
|
||||
```
|
||||
bash 会把它作为三条指令来执行。
|
||||
|
||||
#### 命令与参数
|
||||
|
||||
英语的一句话中,主语后接的是谓语、宾语;
|
||||
bash 的一条指令中,按照空格分隔,第一个单词是要执行的命令,之后如果还有内容的话,只要不是一些特殊的符号(例如 `>`),就是这个命令的参数。
|
||||
例如在下面的命令中:
|
||||
```bash
|
||||
rm file.txt
|
||||
```
|
||||
`rm` 是要执行的命令,`file.txt` 是这个命令的参数。
|
||||
|
||||
在按照空格分割的时候,连续的多个空格与单个空格是等价的,例如下面的命令:
|
||||
```bash
|
||||
rm file.txt
|
||||
```
|
||||
与上面的命令是等价的。
|
||||
|
||||
如果命令或者参数中包含空格,可以用双引号或单引号把它括起来,例如:
|
||||
```bash
|
||||
rm "file with space.txt"
|
||||
```
|
||||
这样 bash 就知道 `file with space.txt` 是传给 `rm` 的一个参数;而不是把它分成 `file`、`with`、`space.txt` 三个参数。
|
||||
也就是说,要删除的是名为 `file with space.txt` 这一个文件,而不是名为 `file`、`with`、`space.txt` 的三个文件。
|
||||
|
||||
每个命令可以接受参数的个数不同。
|
||||
例如,删除文件的命令通常需要至少一个参数(你得告诉它删除哪个文件),至多则不限制;
|
||||
而复制文件的命令通常至少需要两个参数(你得告诉它将哪个文件复制到哪里)。
|
||||
|
||||
#### 内置命令与外部程序
|
||||
|
||||
`cd`、`pwd` 等命令并不会启动 bash 以外的程序:它们是 bash 内置的命令,它们的作用是调整或者输出 bash 本身的状态,
|
||||
相当于查看或者修改 Windows 的资源管理器本身的设置,而不是要 bash 做什么实际的事情。
|
||||
而 `rm file.txt` 这个命令则实际上是启动了一个放置在特定位置[^8]、名为 `rm` 的程序,并将 `file.txt` 作为参数传给它。
|
||||
`mkdir`、`cp` 等命令也是这样的。
|
||||
|
||||
那么,如果要运行一个程序,而这个程序又不放在类似于 `/usr/bin` 这样的特殊位置,应该怎么调用呢?有三个办法:
|
||||
|
||||
* 修改环境变量。新手篇不会介绍这个办法,因为新手很容易把环境变量搞乱。
|
||||
* 使用绝对路径调用程序。例如,这个程序放置在 `/home/chn` 文件夹下,名字叫 `myprogram`,那么可以这样调用:
|
||||
```bash
|
||||
/home/chn/myprogram
|
||||
```
|
||||
如果要传递参数给这个程序,也是一样的写法:
|
||||
```bash
|
||||
/home/chn/myprogram arg1 arg2
|
||||
```
|
||||
* 使用以 `.` 开头的相对路径调用程序。必须使用以 `.` 开头的相对路径(`..` 也可),这就是之前提到的那个重要的例外。
|
||||
例如,这个程序放置在当前文件夹下,名字叫 `myprogram`,那么可以这样调用:
|
||||
```bash
|
||||
./myprogram
|
||||
```
|
||||
|
||||
#### 管道与 `grep` 命令
|
||||
|
||||
除了之前介绍的 `>` 和 `>>` 之外,还有一个非常常用的特殊符号,叫做“管道符号” `|`,就是键盘上那个竖线。
|
||||
它的作用是把一个命令的标准输出重定向到另一个命令的“标准输入”(就是这个命令原本看到的用户的输入[^9])。
|
||||
|
||||
管道符号经常和 `grep` 命令一起使用,`grep` 命令的作用是在输入中查找某个字符串,并输出包含这个字符串的行。
|
||||
例如:
|
||||
```bash
|
||||
cat OUTCAR | grep "Total energy"
|
||||
```
|
||||
这个命令可以输出 `OUTCAR` 文件中包含 `Total energy` 的行。
|
||||
|
||||
`grep` 有一些常用的参数,包括:
|
||||
* `-i`(“ignore case”的缩写):匹配时忽略大小写;
|
||||
* `-An`(“after”的缩写): 除了输出匹配的内容,还输出匹配内容的后几行;
|
||||
* `-Bn`(“before”的缩写): 除了输出匹配的内容,还输出匹配内容的前几行;
|
||||
* `-v`(“invert match”的缩写):输出不匹配的行,而不是输出匹配的行。
|
||||
|
||||
#### 通配符
|
||||
|
||||
使用 `*` 来匹配路径中存在的文件或者文件夹。说起来抽象,举个例子就明白了。假定当前目录下有这样几个文件:
|
||||
```
|
||||
file1.txt
|
||||
file2.txt
|
||||
file3.txt
|
||||
dir1
|
||||
dir1/file.txt
|
||||
dir2
|
||||
dir2/file.txt
|
||||
dir3
|
||||
dir3/file.txt
|
||||
```
|
||||
那么下面这个命令:
|
||||
```bash
|
||||
myprogram *
|
||||
```
|
||||
等价于:
|
||||
```bash
|
||||
myprogram file1.txt file2.txt file3.txt dir1 dir2 dir3
|
||||
```
|
||||
下面这个命令:
|
||||
```bash
|
||||
myprogram dir*
|
||||
```
|
||||
等价于:
|
||||
```bash
|
||||
myprogram dir1 dir2 dir3
|
||||
```
|
||||
|
||||
需要注意的是,`*` 是由 bash 负责解释和展开的,而不是由 `myprogram` 负责解释和展开的;
|
||||
或者说,`myprogram` 从来不知道 `*` 的存在,它收到的信息已经是展开后的结果了。
|
||||
|
||||
另一个常见的通配符是 `~`,它表示当前用户的家目录(也就是你刚登陆时,所在的那个目录[^10])。例如:
|
||||
```bash
|
||||
myprogram ~/file.txt
|
||||
```
|
||||
可能等价于
|
||||
```bash
|
||||
myprogram /home/chn/file.txt
|
||||
```
|
||||
这个通配符也是由 bash 负责解释和展开的。
|
||||
(等等,这个东西是通配符吗?)
|
||||
|
||||
#### for 循环,大括号展开
|
||||
|
||||
bash 也支持 `for` 循环,例如:
|
||||
```bash
|
||||
for i in 1 2 3; do mkdir $i; cd $i; cd ..; done
|
||||
```
|
||||
这个命令会在当前目录下创建三个文件夹,分别叫 `1`、`2`、`3`,然后依次进入这三个文件夹,再依次返回到当前目录。
|
||||
这里用到了 `;` 来分隔多个命令,它的具体用法在新手篇里不会提到,仅在这一个特殊的例子中照葫芦画瓢写就可以了。
|
||||
|
||||
对于数值,bash 还支持大括号展开,例如:
|
||||
```bash
|
||||
|
||||
|
||||
|
||||
[^1]: 这个更底层的程序就是所谓的“内核”。
|
||||
[^2]: 无论是 Windows 上的资源管理器还是 Linux 上的这个“黑框框”,它有一个统一的名字,叫做“shell”,也就是“壳”,意思就是它把系统中复杂的细节包装了起来,让用户可以简单地进行删除文件、打开文件夹等操作。
|
||||
[^3]: Linux 上最常见的是 bash,学校的超算用的就是这个;次常见的是 zsh,我管理的其它服务器使用的其实就是 zsh 而不是 bash。
|
||||
这两个的基本使用方法是相同的,初学者不需要区分。
|
||||
[^4]: WinSCP 默认不会列出隐藏的文件和文件夹,有时会误导新手以为 `.bashrc` 等文件不存在。
|
||||
[^5]: 命令原本输出到屏幕上的内容不仅仅来自标准输出,还有标准错误输出(用于输出出错的信息,例如“permission denied”等)等途径。
|
||||
如此使用重定向符号只会重定向标准输出,不会重定向标准错误输出等其它输出。
|
||||
[^6]: 实际上是“concatenate”的缩写,但这个单词我,反正我不认识。
|
||||
[^7]: 系统在实际复制一个文件夹时,总是需要首先新建文件夹本身,然后新建文件夹里的
|
||||
删除文件夹里的内容,而这又需要首先删除文件夹里的文件夹里的内容,以此类推。
|
||||
“recursive”就是“递归”的意思。单纯删除空文件夹的参数其实是 `-d`,意为“directory”,但这个参数很少用到,因为 `-r` 也可以删除空文件夹。
|
||||
[^8]: 准确说,是 `PATH` 指向的目录。`rm` 等最常用的命令通常位于 `/usr/bin` 或 `/run/current-system/sw/bin`。
|
||||
[^9]: 标准输入也不是程序读取用户输入的唯一途径。最常见的例外是一些需要读取密码的程序,为了防止密码泄漏,它们往往会从更底层直接拦截、读取掉。
|
||||
这也是为什么命令行中输入密码时,大多情况下没有任何显示的原因。
|
||||
[^10]: 准确说,是 `HOME` 环境变量的值。
|
||||
Reference in New Issue
Block a user