Shell与命令行

5.4k 词

主要内容

  1. 基本概念:什么是 Shell,它如何工作。
  2. 文件系统导航:如何在系统中移动和定位。
  3. 文件操作:如何管理文件和目录。
  4. 权限系统:理解谁可以对什么文件做什么。
  5. 组合命令 (管道和重定向):这是命令行最核心、最强大的思想,视频花了大量时间讲解。
  6. 高级交互:通过 sudosysfs 展示命令行的更高阶用途。

Shell 基础:与计算机对话

Shell 是用户与计算机交互的主要方式,尤其适用于图形界面无法完成的任务 。

GUI 擅长“可视化、点选式”的简单任务,Shell 擅长“批量、自动化、远程、底层”的高效控制。

  • 什么是 Shell?: Shell 是一个命令行界面,它接收你输入的命令,解释这些命令,然后让操作系统执行。
  • 命令提示符 (Prompt): 这是你输入命令的地方。这个提示符是可以高度自定义的。
  • 执行程序: 基本语法是 程序名 参数
    • **echo**** 命令**: 这是一个非常基础的命令,作用是把你给它的参数(一段文字)再打印出来。例如,echo hello 会在屏幕上显示 hello
    • 参数中的空格: 如果你的参数本身就包含空格,比如 hello world,你需要用引号把它包起来,写成 echo "hello world",否则 Shell 会认为 helloworld 是两个独立的参数。
1
echo [选项] [字符串]

echo的实际作用:

  • 日志记录器
  • 用户交互提示器
  • 配置生成器
  • 脚本可读性增强器

文件系统导航与路径

这部分教你如何在文件系统中自如地移动。

  • **PATH**** 环境变量**: 当你输入一个命令(如 ls),Shell 是如何知道去哪里找到这个程序的呢?答案是 PATH 环境变量。它包含了一系列目录路径,Shell 会依次在这些目录中寻找你输入的程序。你可以用 echo $PATH 来查看这些路径。
  • **which**** 命令**: 如果你想确切知道一个命令(如 python)对应的是哪个具体文件,可以使用 which python

路径 (Path):

- **绝对路径**: 从根目录 `/` 开始的完整路径,例如 `/home/user/documents`。
- **相对路径**: 从你当前所在的位置开始的路径。
  • 核心导航命令:
    • **pwd**: (Print Working Directory) 显示你当前所在的目录。
    • **cd**: (Change Directory) 更改目录。例如 cd /home 会进入 /home 目录。
    • 特殊符号:
      • . 代表当前目录
      • .. 代表上一级目录
      • ~ 代表你的主目录 (Home Directory)
    • **ls**** 命令**: 列出当前目录下的文件和文件夹。使用 ls -l 可以看到更详细的信息,包括文件权限、所有者、大小和修改日期

cd ../

1
2
3
4
5
6
7
8
假设你当前的工作目录是:
C:\Users\L\Documents\Projects\MyProject\src

cd ../会把你带到C:\Users\L\Documents\Projects\MyProject

cd ../../会把你带到C:\Users\L\Documents\Projects

如果你想访问 C:\Users\L\Documents\Logs\app.log,你可能会从 src 目录中使用 ../../Logs/app.log。

cd ~

1
2
3
4
PS C:\Some\Deep\Folder> 
$cd ~

PS C:\Users\L>

cd - 确实只能和上一次的目录进行切换

它就像一个“记忆功能”,用来让你在当前目录和前一个目录之间来回跳转

1
2
3
4
5
6
7
8
9
10
user@host:/var/log
$ cd /etc

user@host:/etc
$ cd -

user@host:/var/log
$ cd -

user@host:/etc

文件操作与权限

这部分讲解如何创建、移动、复制、删除文件,以及理解Linux/macOS的文件权限系统。

文件权限:

  • ls -l 的输出中,开头的一串字符(如 drwxr-xr-x)代表权限。
    • r 代表读取权限。
    • w 代表写入权限。
    • x 代表执行权限(对于文件是运行,对于目录是进入)。
    • 这串字符分为三组,分别对应文件所有者文件所属组其他用户的权限。

从file和directories角度分析:


  • **r**** (Read):** Lets you view the contents of a file or list the contents (filenames) of a directory.
  • **w**** (Write):**
  • For files: Lets you change or modify the file’s content.
  • For directories: This is the crucial one for deletion! It lets you **create, delete, or rename files and subdirectories **_within_ that directory.
  • **x**** (Execute):**
  • For files: Lets you run the file as a program or script.
  • For directories: Lets you “enter” or cd into the directory and access its contents.

文件操作命令:

- `**mv**`: (Move) 用于移动文件,也可以用来重命名文件。例如 `mv old_name.txt new_name.txt`。
- `**cp**`: (Copy) 复制文件。
- `**rm**`: (Remove) 删除文件。`rm -r` 可以递归删除整个目录(**请谨慎使用!**)。
- `**mkdir**`: (Make Directory) 创建新目录。

cp操作的分解

复制一个文件 (cp source_file destination_file) 实际上是两个独立的步骤:

  1. 读取源文件 (Reading the Source File):
    • 你需要对 源文件 拥有 读取权限 (**r**)。如果没有这个权限,你就无法读取文件的内容,自然也无法复制它。
    • 你还需要对 源文件所在的目录 拥有 执行权限 (**x**),这样才能进入该目录并访问到源文件。
  2. 写入目标位置 (Writing to the Destination Location):
    • 你需要对 目标目录(你要将文件复制到哪里)拥有 写入权限 (**w**)。这是允许你在该目录中创建新文件的权限。
    • 你还需要对 目标目录 拥有 执行权限 (**x**),这样才能进入该目录并在其中执行写入操作。

所以,复制文件 需要以下权限:

  • 对于源文件: 至少需要 **r**** (读取)** 权限。
  • 对于源文件所在的目录: 至少需要 **x**** (执行)** 权限。
  • 对于目标目录: 至少需要 **w**** (写入)** 和 **x**** (执行)** 权限。

rm 命令所需的权限

要成功使用 rm 命令删除一个文件,你必须对该文件的父目录拥有以下权限:

  • **w**** (写入) 权限:** 这是最关键的权限,因为它允许你修改目录的内容(即添加、删除或重命名其中的条目)。没有 w 权限,你就无法从目录中“移除”文件的记录。
  • **x**** (执行) 权限:** 这也是必需的,因为它允许你“进入”或“遍历”该目录。如果没有 x 权限,你就无法访问该目录以进行任何操作,包括删除其内容

mv 跨不同文件系统(复制然后删除)

当你在不同文件系统之间移动文件或目录时(例如,从一个硬盘分区移动到另一个,或从你的本地机器移动到网络共享),mv 实际上执行的是一个复制然后删除的操作。它会先将文件复制到新的文件系统,然后删除旧文件系统中的原始文件。

对于这种更复杂的操作,所需的权限是 cp (复制) 和 rm (删除) 命令所需权限的组合:

获取帮助:

- `**man**`: (Manual) 查看一个命令的官方手册。例如 `man ls` 会显示 `ls` 命令的所有用法和参数。

I/O 重定向与管道

这是命令行最强大的功能之一,它允许你将不同程序的输入和输出连接起来,形成强大的工作流。

  • 输入/输出流: 每个程序都有一个标准输入(stdin)和标准输出(stdout)。
  • 重定向 (Redirection):
    • >: 将程序的输出写入到一个文件中(会覆盖原文件内容)。例如 echo "some text" > file.txt
    • >>: 将程序的输出追加到一个文件的末尾(不会覆盖)。
    • <: 将文件的内容作为程序的输入。例如 cat < file.txt
  • 管道 (Pipe **|**): 这是精髓所在。它将前一个命令的输出直接作为后一个命令的输入
    • 示例: ls -l / | tail -n 1 这个命令分两步:
      1. ls -l / 列出根目录的详细文件列表,并把结果作为输出。
      2. | 管道将这些输出结果传给 tail -n 1 命令,tail -n 1 的作用是只显示输入的最后一行。
      • 这样,你就巧妙地获取了文件列表的最后一行。

echo hello > hello.txt

  • echo hello: echo 命令用于在终端打印字符串。这里它会输出 “hello”。
  • > hello.txt: 这是一个输出重定向操作符。它将 echo hello 命令的标准输出(即 “hello” 这个字符串)重定向到名为 hello.txt 的文件中。
  • 结果: 这会在当前目录下创建一个名为 hello.txt 的文件(如果文件已存在,则会清空其内容),并将 “hello” 写入到该文件中

cat hello.txt

  • cat hello.txt: cat 命令用于显示文件内容。这里它会读取 hello.txt 文件的内容,并将其打印到标准输出(即终端)。
  • 结果: 终端显示 “hello”,证明 hello.txt 中确实写入了 “hello”

cat < hello.txt

  • cat: cat 命令通常接受一个或多个文件名作为参数。如果没有参数,它会从标准输入(通常是键盘)读取。
  • < hello.txt: 这是一个输入重定向操作符。它将 hello.txt 文件的内容重定向为 cat 命令的标准输入。
  • 结果:cat 命令收到 hello.txt 的内容作为输入,并将其打印到标准输出。终端再次显示 “hello”。
  • 注意:cat hello.txtcat < hello.txt 在这种简单情况下效果相同,但底层机制略有不同。cat hello.txtcat 命令自己去打开和读取 hello.txt;而 cat < hello.txt 是 shell 先打开 hello.txt,然后将其内容通过标准输入流传递给 cat 命令。

cat如果没有参数,它会从标准输入(通常是键盘)读取

1
2
3
4
5
$ cat
Hello, this is a test. <-- 你输入的内容,然后按 Enter
Hello, this is a test. <-- cat 立即输出的内容
This is the second line. <-- 你输入的内容,然后按 Enter
This is the second line. <-- cat 立即输出的内容

管道 (Pipe)

数据从左到右流向: 它连接了前一个命令的输出和后一个命令的输入

| 这个符号在命令行中被称为 管道 (Pipe)。它的主要作用是将一个命令的标准输出 (Standard Output) 连接到另一个命令的标准输入 (Standard Input)

| 的工作原理:

当你在两个命令之间使用管道时,shell 会做以下事情:

  1. 执行第一个命令: 第一个命令会正常运行,并将其产生的所有输出(通常是文本)发送到它的标准输出。
  2. 创建缓冲区: shell 会在内存中创建一个临时缓冲区或管道。
  3. 连接I/O: 第一个命令的标准输出不再直接显示在屏幕上,而是被重定向到这个管道缓冲区。
  4. 执行第二个命令: 第二个命令也会正常运行,但它的标准输入不再是键盘,而是被连接到这个管道缓冲区。它会从这个缓冲区读取数据,就像从文件中读取一样。
  5. 数据流: 数据以流的形式从第一个命令流向第二个命令。

超级用户与系统交互

  • **sudo**: (Superuser Do) 当你需要执行一些需要管理员权限的操作时(比如修改系统文件),可以在命令前加上 sudo。系统会提示你输入密码,以确认你有此权限。
  • **/sys**** 文件系统**: 这是一个特殊的虚拟文件系统,它把一些内核参数以文件的形式暴露出来。视频中举例,可以通过修改 /sys 目录下的某个文件来直接调节屏幕亮度,这展示了命令行直接与硬件交互的能力。

为什么需要 sudo

在类 Unix 系统中,出于安全考虑,系统管理员(root 用户)拥有对系统的一切控制权。而普通用户则权限受限,不能随意安装软件、修改系统配置、访问受保护的文件等。

直接使用 root 用户登录或切换到 root 用户 (su) 存在风险:

  1. 误操作风险:root 权限过大,一个小小的失误可能导致系统崩溃或数据丢失。
  2. 安全风险: 如果 root 密码泄露,系统将完全暴露。
  3. 审计困难: 难以追踪具体哪个管理员执行了什么操作。

sudo 解决了这些问题:

  • 提升权限: 允许普通用户在需要时获得临时的、受限的 root 权限来执行特定的命令。
  • 最小权限原则: 用户大部分时间仍然以普通用户身份操作,只在必要时才提升权限。
  • 密码验证:sudo 会要求输入当前用户的密码(而不是 root 密码),这增强了安全性。
  • 审计日志:sudo 会记录哪个用户在何时执行了哪个命令,方便系统管理员进行审计和追踪。
  • 精细控制: 系统管理员可以通过配置 /etc/sudoers 文件来精确控制哪些用户可以运行哪些命令,以及是否需要密码。