启动 shell
大多数 Linux 默认的 shell 是 GNU bash shell,当然还有其他 shell,我们可以查看系统当前可用的 shell:
$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
/usr/bin/screen
查看默认的 shell:
$ echo $SHELL
/bin/bash
查看每个用户默认的 shell(最后一个字段):
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
shell 提示符
进入终端后,就会看到 shell CLI 提示符,这就是我们输入命令的地方。默认的 bash shell 提示符是 $
,表示等待用户输入。
提示符可能包含其他信息,比如在 Ubuntu 上,提示符还会显示当前用户ID,系统名等内容。
pi@raspbian:~$
bash 手册
可以用 man
命令(manual)来访问存储在 Linux 上的手册页面。在想要查找的工具的名称前面输入 man
命令,就能找到那个工具相应的手册条目。比如,想要了解 bash
的信息,可以输入 man bash
,就能看到如下页面:
可以用回车来逐行查看,或用空格来翻页查看,有些终端也支持用鼠标滚轮滚动查看。看完后按 q 退出。
手册将命令分成不同的节,常用的节如下:
节 | 描述 |
---|---|
Name | 显示命令名和一段简短的描述 |
Synopsis | 命令的语法 |
Configuration | 命令配置信息 |
Description | 命令的一般性描述 |
Options | 命令选项描述 |
Environment | 描述所使用的环境变量 |
如果不记得命令名,可以用关键字搜索手册,语法是:man -k 关键字
浏览文件系统
在 Windows 中,每个磁盘对应一个盘符,文件路径以一个盘符开头。
而在 Linux 中,所有文件都存储在一个虚拟目录(virtual directory)结构中,该结构以根(root)目录开头,根目录下的目录和文件会按照访问它们的目录路径一一列出(与 Windows 类似)。比如:
/home/pi/code/python/
Linux 路径本身并没有提供任何关于文件存在哪个物理磁盘上的信息。在 Linux PC 上安装的第一块硬盘称为根驱动器,根驱动器包含虚拟目录的核心。如果安装其他磁盘,Linux 会在根驱动器上创建一些特别的目录,称为挂载点(mount point),挂载点中的文件和目录存储在其他磁盘中。
一般来说,系统文件存在根驱动器中,用户文件存在其他驱动器。(就像 Windows 的 C: 盘和 D: 盘)
常见的 Linux 目录名称有:
目录 | 用途 |
---|---|
/ | 根目录,通常不会在这里存储文件 |
/bin | 二进制目录,存放用户级 GNU 工具 |
/boot | 启动目录,存放启动文件 |
/dev | 设备目录,Linux 在这里创建设备节点 |
/home | 主目录,Linux 在这里创建用户目录 |
/lib | 库目录,存放系统和应用程序的库文件 |
/media | 媒体目录,可移动媒体设备的挂载点 |
/mnt | 挂载目录,另一个可移动媒体设备的挂载点 |
/opt | 可选目录,常用于存放第三方软件包和数据文件 |
/proc | 进程目录,存放现有硬件及当前进程的相关信息 |
/root | root用户的主目录 |
/sbin | 系统二进制目录,存放 GNU 管理员级工具 |
/run | 存放系统运行时的运行时数据 |
/srv | 服务目录,存放本地服务的相关文件 |
/sys | 系统目录,存放系统硬件信息的相关文件 |
/tmp | 临时目录,存放临时文件 |
/usr | 用户二进制目录,存放用户级 GNU 工具 |
/var | 可变目录,存放经常发生变化的文件,比如日志文件 |
常见的目录名是基于文件系统层级标准(filesystem hierarchy standard, FHS),很多 Linux 发行版都遵循了 FHS。我们可以在 https://www.pathname.com/fhs/ 查看最新 FHS 标准。
当登录到 CLI 后,会话将从主目录开始,主目录是分配给用户账户的一个特有目录。
遍历目录
可以使用 cd
目录将 shell 会话切换到另一个目录,格式为:cd 目录
目录可以用绝对路径或相对路径表示。
- 绝对文件路径:从根目录开始,即以
/
开头 - 相对文件路径:从当前位置开始
波浪号 ~
表示用户的主目录,我们可以用它来简化路径。比如 cd ~
表示回到主目录,或者直接输入 cd
也能回到主目录。
如果不知道当前位置,可以用 pwd
来查看。
有两个特殊字符可以用在相对文件路径中:
-
.
:表示当前目录 -
..
:表示当前目录的父目录
可以用多个 ..
来向上切换目录。比如说 cd ../../
表示回到上两级目录。
文件和目录列表
可以用 ls
查看当前目录下的文件和目录:
$ cd /
$ ls
bin dev home lost+found mnt proc run srv sys usr
boot etc lib media opt root sbin swapfile tmp var
可以用 ls 目录
来查看特定目录下的文件和目录。
$ ls /
bin dev home lost+found mnt proc run srv sys usr
boot etc lib media opt root sbin swapfile tmp var
如果是彩色终端,ls命令还可以用不同颜色来区分不同类型的文件。如果没安装彩色终端,可以用 ls -F
来区分文件和目录:
$ ls -F /
bin/ dev/ home/ lost+found/ mnt/ proc/ run/ srv/ sys/ usr/
boot/ etc/ lib/ media/ opt/ root/ sbin/ swapfile tmp/ var/
ls命令会隐藏以 .
开头的文件,要显示隐藏文件,可以用 ls -a
$ ls -a
. .aspnet .bash_logout .cache .config .local .python_history
.. .bash_history .bashrc code .gnupg .profile .Xauthority
如果想要递归显示子目录下的文件,可以用 ls -R
$ ls -R
.:
jellyfin vscode-cpptools
./jellyfin:
./vscode-cpptools:
ipch
如果想显示详细信息,可以用 ls -l
$ ls -l
total 1048660
drwxr-xr-x 2 root root 4096 Jan 2 23:47 bin
drwxr-xr-x 5 root root 16384 Jan 1 1970 boot
drwxr-xr-x 17 root root 3660 Feb 2 18:07 dev
drwxr-xr-x 113 root root 4096 Jan 20 17:33 etc
drwxr-xr-x 3 root root 4096 Jan 2 22:35 home
每一行包括下述信息:
- 文件类型,比如目录(d)、文件(-)、字符型文件(c)或块设备(b)
- 文件的权限
- 文件的硬链接总数
- 文件属主的用户名
- 文件属组的组名
- 文件的大小(byte)
- 文件的上次修改时间
- 文件名或目录名
如果只想查找特定文件,可以用以下几种通配符:
-
?
代表一个字符 -
*
代表零个或多个字符 -
[ai]
代表从中括号中选择一个字符 -
[a-i]
从 a 到 i 中选择一个字符 -
[!a]
排除 a
处理文件
创建文件
用 touch
创建空文件,如果文件已经存在,就会改变文件的修改时间。
$ touch test
$ ls
test
复制文件
复制文件可以用 cp
,语法如下:
cp source destination
如果 source 和 destination 都是文件名,则把源文件复制成一个新文件,并以 destination 命名。如果目标文件已存在,则默认会覆盖,想要不覆盖,可以加上 -i
选项。
如果 destination 是目录,则会复制到目录下。为了区分目录名与文件名,要求目录名要以斜杠 / 结尾。如果想要将某个文件复制到当前目录,可以用单点符 .
来表示当前目录:
$ cp test .
也可以用前面说的通配符,把符合条件的文件复制到目录下:
$ cp *scripts mod_scripts/
如果想要复制一个目录,就需要用到 -R
参数,表示递归复制整个目录的内容,比如:
$ cp -R source/ destination/
表示将 source 目录中的内容复制到 destination 中。
自动补全
在输入文件名输入到一半时,可以按以下 Tab 键,就会自动补全整个文件名。此外,自动补全也可以用于补全命令。
链接文件
要维护同一文件的多份副本,可以给一个物理文件创建多个虚拟副本,这种副本称为 链接。链接有两种:
- 软链接(符号链接)
- 硬链接
关于这两个的区别,可以去看知乎
软链接就是一个真实的文件,它有自己的大小、权限等等,但它指向的是另一个文件。我们可以用 ln -s
创建软链接:
$ ls -l test
-rw-r--r-- 1 pi sudo 27 Feb 5 21:40 test
$ ln -s test sl_test
$ ls -l *test
lrwxrwxrwx 1 pi sudo 4 Feb 5 21:40 sl_test -> test
-rw-r--r-- 1 pi sudo 27 Feb 5 21:40 test
注意到软连接和源文件的权限、大小都不同(大小是 sudo 后面那个数),另外,软链接的 inode 编号(用于标识文件和目录的编号)与源文件不同。我们可以用 ls -i
查看 inode 编号:
$ ls -i *test
18254 sl_test
18253 test
硬链接则相反,它是一个虚拟的文件,它的信息和源文件是一样的。可以用 ln
创建硬链接:
$ ls -il *test
18253 -rw-r--r-- 1 pi sudo 27 Feb 5 21:40 test
$ ln test hl_test
$ ls -il *test
18253 -rw-r--r-- 2 pi sudo 27 Feb 5 21:40 hl_test
18253 -rw-r--r-- 2 pi sudo 27 Feb 5 21:40 test
注意到两个文件的 inode 编号是一样的,并且大小、权限是一样的。
另外注意一下 pi 前面那个数字,指的是某个文件的硬链接数+1,所以当建立了硬链接后,就从 1 变成了 2.
那么什么时候硬,什么时候软呢?👉👌 我们有如下原则:
- 如果想在不同存储媒体之间建立链接,则只能用软链接。
- 不要创建软链接的软链接,这会造成混乱。
重命名与移动
用 mv
可以完成重命名与移动文件/目录,它的用法如下:
$ mv source destination
mv 会把 source 移到 destination 并重命名为 destination,但 inode 编号和时间戳保持不变。与 cp 类似,我们可以加上 -i
参数,避免覆盖已有文件。
删除
可以用 rm
来删除文件,建议加上 -i
,这样删除前,shell 会确认是否会删除,防止误删。
如果要删除非空目录,需要加上 -r
,即递归删除。
处理目录
创建目录
用 mkdir dir_name
可以创建一个名为 dir_name 的目录。
如果想要创建多级目录,需要用 mkdir -p new_dir/sub_dir/under_dir
删除目录
对于空目录,可以用 rmdir
或 rm
对于非空目录,可以用 rm -r
查看文件内容
查看类型:file file_name
查看文本文件:如果是比较短的文件,就用 cat
,如果是比较长的文件,可以用 more
或 less
查看文件的开头或结尾:head
或 tail