Shell Magic

对计算机的学生而言,许多开发工具是未来老师或企业默认你已经“精通”的,然而未经学校系统培训的我们或许会对此感到迷茫,正如 MIT 课程 The Missing Semester of Your CS Education 所强调的: “掌握基础工具是程序员的核心竞争力”。这个课程会帮助你入门、了解一些计算机常用的开发工具,也算是程序员的自我修养吧!Let’s Go!😄

相关课程在b站也有双语翻译(大部分应该都能听懂,就是有个好像是西班牙的老师带点口音听起来有点不适应😢)[自制双语字幕] 计算机教育缺失的一课(2020) - 第1讲 - 课程概览与 shell


  不论是在电影里还是在我们初识计算机的过程中,都会看到一个黑乎乎的窗口,只要输入几行代码就可以完成酷炫的操作,但是你或许对这有一点疑惑,这到底是terminalbashzsh还是powershell,他们到底是如何区分的呢?

1.Terminal:用户终端,用来启动shell,这也可以说算是一个“工具”,活跃在为用户服务的前端
2.Shell:是一个命令行解释器,负责接收用户输入的命令并将其解释为计算机可以执行的操作,与Terminal相比,是活跃于用户服务后端的程序,以下都是Shell在不同操作系统中的实现:

  • Bash:是一种常用的Shell,在LinuxmacOS中默认安装。
  • Zsh:是一种功能强大的Shell,在macOS中默认安装,也可以在Linux中安装。
  • PowerShell:是一种Windows系统下的命令行工具,用于管理Windows系统执行PowerShell脚本

Shell

  当熟悉的可视化界面无法实现你想要的功能时,Shell将成为你与计算机交互的强大工具。相比图形界面有限的按钮和滑块,命令行提供了更灵活、更强大的控制方式,允许你通过文本命令和脚本实现自动化操作。本文基于VMware虚拟机中的Ubuntu 22.04发行版演示基础Shell操作:

1
2
richard@richard-VMware-Virtual-Platform:~$ date
Sat Jul 26 03:27:54 PM CST 2025

第一行通常是用户名、机器名称和当前所在路径

  • Windows中路径通常使用反斜杠\分隔,每个驱动器都有一个单独的路径结构。
  • Linux / macOS 中这些路径使用正斜杠/分隔,他们挂载在同一个命名空间下。

开头的斜杠表示从文件系统的顶部开始。

  • 相对路径:相对于当前位置的路径
  • 绝对路径:完整路径,从顶部开始

1
2
richard@richard-VMware-Virtual-Platform:~$ echo "Hello World"
Hello World

echo可以将后面的参数打印在屏幕上

1
2
richard@richard-VMware-Virtual-Platform:~$ which echo
/usr/bin/echo

which可以用于寻找后面参数文件的绝对位置

1
2
richard@richard-VMware-Virtual-Platform:~$ pwd
/home/richard

pwdPrint Working Directory打印当前所在路径

1
2
richard@richard-VMware-Virtual-Platform:~$ cd /home
richard@richard-VMware-Virtual-Platform:/home$

cdChange Directory)表示更改当前目录

这是更方便切换目录的方式:

  • .表示当前目录
  • ..表示目录

注意:使用相对路径能提高命令在不同电脑上的兼容性


1
2
3
4
5
6
7
richard@richard-VMware-Virtual-Platform:/$ ls
bin home mnt sbin.usr-is-merged usr
bin.usr-is-merged lib opt snap var
boot lib64 proc srv
cdrom lib.usr-is-merged root swap.img
dev lost+found run sys
etc media sbin tmp

ls会列出当前目录中的文件,这能够快速浏览文件

1
2
richard@richard-VMware-Virtual-Platform:/home$ cd ~
richard@richard-VMware-Virtual-Platform:~$
  • cd ~能够快速回到用户主目录
  • cd -切换到上一个工作目录

1
2
3
4
richard@richard-VMware-Virtual-Platform:~$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

--help参数显示命令帮助信息


1
2
3
4
5
6
7
8
richard@richard-VMware-Virtual-Platform:~$ ls -l
total 40
drwxr-xr-x 2 richard richard 4096 Mar 9 10:21 Desktop
drwxr-xr-x 2 richard richard 4096 Mar 9 10:21 Documents

lrwxrwxrwx 1 root root 7 Apr 22 2024 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Feb 26 2024 bin.usr-is-merged
# 仅列举部分进行展示说明

文件类型(第1个字符)

字符 类型 说明 示例
d 目录 文件夹 drwxr-xr-x
- 普通文件 文本/二进制文件 -rw-r--r--
l 符号链接 软链接文件 lrwxrwxrwx
c 字符设备 终端等串行设备 crw--w----
b 块设备 磁盘等存储设备 brw-rw----
s 套接字 进程通信文件 srwxrwxrwx
p 管道 FIFO 管道文件 prw-------

用户权限分为 3组(每组3字符),分别对应:

组别 示例
所有者权限 rwx
所属组权限 r-x
其他用户 r-x

权限字符含义

字符 权限 对文件的影响 对目录的影响
r 查看文件内容 列出目录内容(ls
w 修改/删除文件 创建/删除目录内文件
x 执行 运行程序/脚本 进入目录(cd
- 无权限 无权限

⚠️注意

  1. 即使文件本身有 w 权限,如果所在目录没有 w,你只能清空或删除文件内容,却仍然无法删除或重命名
  2. 如果我想要访问一个目录,必须拥有其所有父目录的权限/usr/bin/echo我必须拥有/usr /bin目录的权限,否则我将不被允许访问该文件,因为我将无法进入其中的目录

mv能将文件修改位置并重命名
cp复制文件 需要两个参数 一个要复制的文件路径 一个目标文件路径
rm用于删除文件
rmdir删除一个目录 但它只能删除空目录 防止不小心删除一大堆文件
mkdir创建目录

1
mkdir My Photos

mkdir创建目录

1
mkdir "My Photos"

这里如果不加上上引号则会创建"My"和"Photos"两个目录,因为Bash(或其他 Shell)会将空格视为命令参数的分隔符,相当于命令收到了两个独立的参数,因此它会创建两个独立的目录!

或者使用反斜杠来转义空格,反斜杠会告诉 Shell:下一个字符是普通字符,不要把它当做特殊符号处理!

1
mkdir My\ Photos

man+指令 查找手册

ctrl+l清空窗口

输入流和输出流

1
richard@richard-VMware-Virtual-Platform:~$ echo hello > hello.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
richard@richard-VMware-Virtual-Platform:~$ ls > hello.txt
richard@richard-VMware-Virtual-Platform:~$ cat hello.txt
Desktop
Documents
Downloads
fizzbuzz.py
hello2.txt
hello.txt
Music
Pictures
Public
snap
Templates
Videos
web

这样就可以将输出到屏幕的信息存储起来!

  • >覆盖输出到文件
  • <从文件读取输入

1
2
richard@richard-VMware-Virtual-Platform:~$ cat hello.txt
hello

通过cat指令输出文件内容

1
2
3
richard@richard-VMware-Virtual-Platform:~$ cat <hello.txt>hello2.txt
richard@richard-VMware-Virtual-Platform:~$ cat hello2.txt
hello

<hello.txt作为输入内容并通过>cat打印的任何内容输出到hello2.txt文件中

1
2
3
4
richard@richard-VMware-Virtual-Platform:~$ cat <hello.txt>>hello2.txt
richard@richard-VMware-Virtual-Platform:~$ cat hello2.txt
hello
hello

>>表示追加而不是覆盖(append instead of overwrite)

1
2
richard@richard-VMware-Virtual-Platform:~$ ls -l|tail -n1
drwxrwxr-x 3 richard richard 4096 Mar 9 12:26 web

管道运算符|作用是将左侧命令的输出作为右侧命令的输入:可以连接多个命令形成处理流水线

tail将输出最后一行的内容


用户权限管理

root相当于Windows的管理员权限,是一位超级用户,可以做任何想做的事情,但是倘若一直使用root用户操作计算机,如果运行了错误的程序,那会彻底毁坏你的电脑!

1
2
3
richard@richard-VMware-Virtual-Platform:/sys/class/backlight$ sudo su
[sudo] password for richard:
root@richard-VMware-Virtual-Platform:/sys/class/backlight#

通过sudo su来进入root身份,同时提示符由$变为#


1
2
3
root@richard-VMware-Virtual-Platform:/sys/class/backlight# exit
exit
richard@richard-VMware-Virtual-Platform:/sys/class/backlight$

exit来退出用户权限


1
richard@richard-VMware-Virtual-Platform:~$ xdg-open hello.txt

这样就可以直接在terminal打开文件!


1
2
3
richard@richard-VMware-Virtual-Platform:~$ foo=bar
richard@richard-VMware-Virtual-Platform:~$ echo $foo
bar

shell中,$符号是一个特殊字符,主要用于变量展开。当你在变量名前面加上$时,shell会将其替换为该变量的值!

  • foo 会被Shell视为普通字符串
  • $foo 告诉Shell这是一个需要展开的变量

1
2
3
4
5
6
7
richard@richard-VMware-Virtual-Platform:~$ echo "Hello"
Hello
richard@richard-VMware-Virtual-Platform:~$ foo=World
richard@richard-VMware-Virtual-Platform:~$ echo "Hello foo"
Hello foo
richard@richard-VMware-Virtual-Platform:~$ echo "Hello $foo"
Hello World

shell中我们一定要非常注意空格space的使用,它是用作不同参数间的分隔符,倘若多打一个可能就会出现报错!

1
2
3
4
5
6
richard@richard-VMware-Virtual-Platform:~$ false
richard@richard-VMware-Virtual-Platform:~$ echo $?
1
richard@richard-VMware-Virtual-Platform:~$ true
richard@richard-VMware-Virtual-Platform:~$ echo $?
0

$? 是一个特殊变量,存储上一个命令的退出状态码

  • false 是一个 Shell 内置命令,返回非零退出状态(失败)设置退出状态码为 1(表示失败)
  • true 也是一个 Shell 内置命令,返回零退出状态(成功)退出状态码被设为 0(表示成功)

  这里看上去有点反常理,我们学的其他编程语言中0false,非零是true,为什么这里反过来了?
  当我们想到cc++main函数结束的返回值或许就不奇怪了!main() 函数默认返回0 表示成功,非零表示错误(如 return 1;)。

再考虑到程序运行只有两种可能:

  1. 完全成功(唯一状态 0
  2. 失败(可能有多种原因,用不同非零值区分):
  • 0 = 没有错误(成功)
  • 1 = 通用错误
  • 2 = 参数错误
  • 3 = 文件不存在
1
2
3
4
richard@richard-VMware-Virtual-Platform:~$ false || echo "Oops fail"
Oops fail
richard@richard-VMware-Virtual-Platform:~$ true || echo "Will be not be printed"
richard@richard-VMware-Virtual-Platform:~$

shell||同样遵循短路原则&&同理!

1
2
richard@richard-VMware-Virtual-Platform:~$ echo "We are now at $(pwd)"
We are now at /home/richard

shell中使用$(command)进行命令替换


1
2
3
4
5
richard@richard-VMware-Virtual-Platform:~$ ls
Desktop Downloads hello.txt Pictures snap Videos
Documents hello2.txt Music Public Templates web
richard@richard-VMware-Virtual-Platform:~$ ls *.txt
hello2.txt hello.txt

*是一个通配符globbing):表示匹配任意数量的任意字符包括零个字符)。Shell会在执行ls 前先展开 *.txt,将其替换为所有匹配的文件名,相当于寻找所有后缀为.txt的文件!

1
2
3
4
richard@richard-VMware-Virtual-Platform:~$ ls hello?.txt
hello2.txt
richard@richard-VMware-Virtual-Platform:~$ ls hello*.txt
hello2.txt hello.txt

这里可以看到?也是通配符,表示匹配任意一个字符(区别是必须存在,不能匹配空字符

1
#!/usr/bin/env python3 #自动查找python3

通过Shell调用Python脚本可以充分发挥两者的优势:Shell流程控制能力结合Python丰富库函数,但我们要在路径中找到并配置好python解释器。

1
import sys

由于shell默认不会执行python指令,我们需要添加库函数,来让python接受shell传递的参数

1
richard@richard-VMware-Virtual-Platform:~$ history

我们可以使用⬆️来一个个浏览历史记录命令,我们也可以使用history直接打印所有历史命令!

1
richard@richard-VMware-Virtual-Platform:~$ history | grep git

我们通过history +N | grep +指令来查找所有与指令字符串相匹配的N条历史记录命令!

1
tree

能列出目录结构性的位置!


wc(word count)是一个用于统计文本文件中单词、行、字符等命令行工具

1
wc [选项参数]... [文件]...

可选参数:

  • c--bytes: 显示字节数
  • m--chars: 显示字符数 对于多字节字符(如中文),这与 -c 不同
  • w--words: 显示单词数(以空格、制表符、换行符分隔的字符串)
  • l--lines: 显示行数
  • 不指定任何选项: 默认会同时显示行数、单词数、字节数,以及文件名
1
2
richard@richard-VMware-Virtual-Platform:~$ wc hello.txt
13 13 109 hello.txt
1
2
richard@richard-VMware-Virtual-Platform:~$ wc --word hello.txt
13 hello.txt

关机与重启

1.shutdown

  • -r--reboot: 重新启动系统
  • -h--halt: 关闭系统
  • -c--cancel: 取消之前的计划关机或重启
  • -t--time <时间>: 指定关机或重启的时间(格式:HH:MM
  • -k--kill: 不关机,只发送SIGTERM信号给所有进程
1
2
richard@richard-VMware-Virtual-Platform:~$ shutdown -r
Reboot scheduled for Tue 2025-09-02 12:05:06 CST, use 'shutdown -c' to cancel.

2.reboot

  • -f--force: 强制重启,不发送SIGTERM信号
  • -n--no-fsync: 不执行fsync系统调用,加快重启速度
  • -w--wait: 等待所有进程结束后再重启
  • -i--init: 关机之前,关闭所有网络接口
  1. init
  2. poweroff

WSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
❯ wsl --list --online
以下是可安装的有效分发的列表。
使用“wsl.exe --install <Distro>”安装。

NAME FRIENDLY NAME
Ubuntu Ubuntu
Ubuntu-24.04 Ubuntu 24.04 LTS
openSUSE-Tumbleweed openSUSE Tumbleweed
openSUSE-Leap-16.0 openSUSE Leap 16.0
SUSE-Linux-Enterprise-15-SP7 SUSE Linux Enterprise 15 SP7
SUSE-Linux-Enterprise-16.0 SUSE Linux Enterprise 16.0
kali-linux Kali Linux Rolling
Debian Debian GNU/Linux
AlmaLinux-8 AlmaLinux OS 8
AlmaLinux-9 AlmaLinux OS 9
AlmaLinux-Kitten-10 AlmaLinux OS Kitten 10
AlmaLinux-10 AlmaLinux OS 10
archlinux Arch Linux
FedoraLinux-43 Fedora Linux 43
FedoraLinux-42 Fedora Linux 42
eLxr eLxr 12.12.0.0 GNU/Linux
Ubuntu-20.04 Ubuntu 20.04 LTS
Ubuntu-22.04 Ubuntu 22.04 LTS
OracleLinux_7_9 Oracle Linux 7.9
OracleLinux_8_10 Oracle Linux 8.10
OracleLinux_9_5 Oracle Linux 9.5
openSUSE-Leap-15.6 openSUSE Leap 15.6
SUSE-Linux-Enterprise-15-SP6 SUSE Linux Enterprise 15 SP6
1
2
3
4
5
6
7
8
9
10
11
12
❯ wsl --install Debian
正在下载: Debian GNU/Linux
正在安装: Debian GNU/Linux
已成功安装分发。可以通过 “wsl.exe -d Debian” 启动它
正在启动 Debian...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: richard
New password:
Retype new password:
passwd: password updated successfully
usermod: no changes
1
2
3
4
5
(base) PS C:\Users\Legion> wsl -l -v
NAME STATE VERSION
* Ubuntu Running 2
Debian Running 2
docker-desktop Stopped 2

Scripts

30分钟Shell光速入门教程

1
richard@LAPTOP-THUPDMQ0:~/test$ vim hello.sh
1
2
3
4
5
#!/bin/bash

echo "Hello Shell"
date
whoami
  • #!/bin/bash叫做Shebang,作用是告诉操作系统这个脚本需要用/bin/bash这个解释器执行
1
2
3
4
5
richard@LAPTOP-THUPDMQ0:~/test$ chmod a+x hello.sh
richard@LAPTOP-THUPDMQ0:~/test$ ./hello.sh
Hello Shell
Sat Jan 17 12:36:15 AM CST 2026
richard
  • chmod a+x hello.shchmod 是 “change mode” 的缩写,作用是修改文件的权限chmod [用户范围][操作符][权限] 文件名

权限针对的三类用户:

指令 含义
u (user) 文件的所有者
g (group) 文件所属组的用户
o (others) 其他所有用户
a (all) 等同于 u+g+o,即所有用户

权限的三种核心类型:

指令 含义
r (read) 读取文件内容的权限
w (write) 修改 / 删除文件内容的权限
x (execute) 执行文件的权限(对脚本 / 程序来说,没有 x 权限就无法运行)

猜数字小游戏

下面是一个猜数字小游戏来练习简单的shell语法!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash

channel="猜数字小游戏"
echo "请输入您的姓名"
read name
echo "您好,$name,欢迎来到$channel "
number=$(shuf -i 1-10 -n 1)
echo $number
while true
do
echo "请输入一个1-10之间的数字"
read guess
if [[ $guess -eq $number ]]; then
echo "恭喜您猜对了!是否继续?(y/n):"
read choice
if [[ $choice = "y" ]] || [[ $choice = "Y" ]]; then
number=$((RANDOM%10+1))
echo $number
continue
else
break
fi
elif [[ $guess -lt $number ]]; then
echo "小了"
else
echo "大了"
fi
done

echo "游戏结束,再见!"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
richard@LAPTOP-THUPDMQ0:~/test$ ./hello.sh
请输入您的姓名
richard
您好,richard,欢迎来到猜数字小游戏
6
请输入一个1-10之间的数字
4
小了
请输入一个1-10之间的数字
6
恭喜您猜对了!是否继续?(y/n):
y
1
请输入一个1-10之间的数字
3
大了
请输入一个1-10之间的数字
1
恭喜您猜对了!是否继续?(y/n):
n
游戏结束,再见!
  • 远程传输文件
1
scp -P 31985 ASC1598@36.151.243.90:/home/ASC1598/"Instruction Manual of Remote Login Platform.pdf" C:\Users\Legion\Desktop\

Shell Magic
http://example.com/2025/07/27/Tutorial/Shell-Magic/
Author
Li Qinxuan
Posted on
July 27, 2025
Updated on
January 23, 2026
Licensed under