了解一些 shell 的基本特性
更多精彩
- 更多技术博客,请移步 IT人才终生实训与职业进阶平台 - 实训在线
3.1 启动 shell
- 登录 Linux 时会启动的 shell 类型,由用户配置文件决定,该配置文件位于
/etc/passwd - 打开该文件可以看到如下内容
-
每一行记录的最后一段内容就是制定了用户使用的 shell 类型
-
3.2 shell 提示符
- 默认的 shell 提示符是美元符号 $ ,但现在很多 shell 工具都支持对其进行修改
-
比如下图中是我日常使用的终端,就是使用的 iTerm2 + zsh 的语法
3.3 bash 手册
- 大多数 Linux 发行版自带用来查找 shell 命令和其他 GNU 工具信息的在线手册
3.3.1 man 命令查看手册
- 想要访问 Linux 的帮助手册,可以使用
man 命令 - 在想要查找的工具名称前面输入 man 命令,就可以获取该工具的相关条目
- 下图就是输入
man ls 之后得到的信息- 手册通过 分页程序 进行显示,可以使用空格键进行翻页,或回车键进行逐行查看
- 按 Q 键可以退出当前手册 ,按 Ctrl + C 是无法退出手册的
3.3.2 手册的区域号
- 上图中左上角的 LS(1) 表示的意思是该命令是 可执行程序或 shell 命令
-
这个区域还会显示其他数值,如下图
3.3.3 不同系统对 help 指令的识别情况
-
下图中的终端连接的是 CentOS 的系统,可以正常的使用
ls --help 查看该命令的帮助信息
-
下图中的终端是 macOS 系统,基于 Unix 的终端,尝试了多种形式的 help 指令都是无效的
3.4 浏览文件系统
3.4.1 Linux 文件系统
- Linux 在路径名中不使用驱动器盘符,不会像 Windows 一样存在 C 盘 D 盘的概念
- Linux 将文件存储在单个目录结构中,被称为 虚拟目录( Virtual Directory )
- 该虚拟目录只包含一个根目录作为基础目录
- 下图中表示的就是当前位于
/Users/asing1elife/Documents 的目录下-
路径本身并没有提供任何有关当前处于哪个物理磁盘上的信息
-
- 在 Linux PC 上安装的第一块硬盘是 根驱动器
- 根驱动器包含了虚拟目录的核心,其他目录都是从这里开始创建
- Linux 会在根驱动器上创建一些特别的目录,被称为 挂载点( Mount Point )
- 挂载点是虚拟目录中用于分配额外存储设备的目录
- 虚拟目录会让文件和目录出现在这些挂载点目录中,但实际这些文件和目录存储在另外一个硬盘中
- 通常系统文件会存储在根驱动器中,也叫 系统盘
- 而用户文件存储在另外驱动器中,也叫 数据盘
- 在 Linux 中,通用的目录名用于表示一些常见的功能,如下图
- 常见的目录名称基于 文件系统层级标准( Filesystem Hierarchy Standard ,FHS )
3.4.2 cd 命令遍历目录
-
cd directoryName 命令用于实现 从一个目录切换到另一个目录 - 下图中,用户本来处于
/Users/asing1elife 目录,使用cd Documents 后,就切换到了Users/asing1elife/Documents 目录-
pwd 命令用于显示 当前工作目录
-
- 如果在
cd 后面不指定目标路径,则会直接切换到用户主目录,如下图 -
cd 后面的目标路径有两种表现形式- 绝对文件路径
- 相对文件路径
3.4.2.1 绝对文件路径
- 要使用绝对文件路径来切换到系统的某个特定位置,需要在
cd 命令后指定完整的路径名称,如下图
3.4.2.2 相对文件路径
-
要跳转到基于当前位置的目标路径,使用相对文件路径是更简洁的方法,如下图
- 可以看到,同样是跳转到
/Documents 目录,使用相对路径比使用绝对路径要简洁很多
- 可以看到,同样是跳转到
- 可以在任何包含子目录的目录中使用相对路径来进行快速的目录跳转
- 也可以使用以下两个字符来丰富相对路径的功能
- 单点符号,表示当前目录
- 双点符号,表示当前目录的父目录
- 如下图,展现了使用相对路径时添加 单点符号 和 双点符号 后的效果
- 单点符号的添加看上去没有什么意义,但我认为这可以更清晰的表示 是从当前目录向下级子目录跳转
- 双点符号则是让相对路径跳转的功能更强大,可以实现 从当前目录跳转到父级目录后在进入其它目录
3.5 文件和目录列表
3.5.1 ls 命令基本列表功能
-
ls 命令的最基本形式是 显示当前目录下的文件和目录 ,如下图-
输出的列表按字母排序
-
3.5.1.1 使用 -F 区分文件和目录
- 可以看到上图中用不同颜色显示了文件和目录,这是因为当前使用的终端支持彩色显示
- 如果终端不支持彩色显示,可以通过
ls -F 来实现文件和目录的区分,如下图- 文件后面会添加一个星号
-
目录后面会添加一个斜杠
3.5.1.2 使用 -a 显示隐藏文件
- Linux 经常使用隐藏文件来保存配置信息,要在当前目录显示出隐藏信息,只需要使用
ls -a 即可,如下图-
文件或目录开头有一个单点符号的就表示隐藏文件
-
3.5.1.3 使用 -R 显示子目录
- 如果想要查看当前目录的所有子目录,但是又不想挨个目录的进去查看,可以使用
ls -R ,如下图- 需要注意的是,该指令会通过递归的形式,显示当前目录的所有子目录,所以不要在层级太高的目录中使用
-
如果不小心在根目录使用了该指令,则可能会导致当前窗户输出特别特别多的信息
3.5.1.4 使用合并参数简化操作
- 如果想在查看目录的同时区分文件和目录、显示隐藏文件、显示子目录,可以将参数直接拼接,如下图
- 不用每个参数都添加短横杠来标记参数
-
可以直接使用一个短横杠来拼接所有想要使用的参数
3.5.1.5 使用 -i 显示文件 inode 编号
- Linux 在创建文件时会为每个文件指定一个独立的 inode 编号,使用
ls -i 就可以查看到该编号,如下图
3.5.2 ls -l 命令显示长列表
- 使用
ls -l 可以在显示文件和目录列表的同时显示对应的附加信息,如下图
3.5.3 ls 命令过滤输出列表
-
ls 命令支持在命令中定义列表过滤规则,如下图 -
ls 通过定义过滤规则来显示当前目录的部分内容,只支持过滤文件,如果是目录的话,则会直接显示该目录中的内容,如下图- 输入
ls -l exmaple.txt 是将当前目录列表过滤到只显示example.txt - 输入
ls l child2 则是直接显示了child2 目录中的内容
- 输入
3.5.3.1 ls 命令使用元字符通配符过滤输出列表
-
ls 命令使用通配符过滤输出列表,被称为 文件扩展匹配( File Globbing ) - 如果不能确认完整的文件名称,则可以使用 元字符通配符( Metacharacter Wildcards ) 来扩大过滤范围
- 元字符通配符的类别支持以下两种
- 问号,代表一个字符
- 星号,代表零个或多个字符
- 下图中,使用
exa 开头,mple.txt 结尾的文件一共有 3 个- 输入
ls -l exa?mple.txt ,只能显示 1个文件,说明问号只能匹配一个字符 - 输入
ls -l exa*mple.txt ,可以显示 3 个文件,说明星号可以匹配零个或多个字符
- 输入
3.5.3.2 ls 命令使用其他通配符过滤输出列表
- 其他通配符的类别支持以下两种
- 中括号,可以指定字符范围
- 感叹号,可以排除指定字符
- 下图中,使用
exa 开头,mple.txt 结尾的文件一共有 4 个- 输入
ls -l exa[b-c]mple.txt ,可以显示两个文件,说明[b-c] 表明 b 到 c 之间的字符都满足匹配 - 输入
ls -l exa[!b]mple.txt ,只能显示一个文件,说明[!b] 表明排除字符 b
- 输入
-
上图中使用感叹号做排除匹配时,在感叹号之前加了一个反斜杠,因为该测试是在 macOS 中执行的,如果不加反斜杠,会抛出语法错误,下图中的效果是使用 CentOS 执行的,不需要加反斜杠
3.5.3.3 ls -d 过滤目录文件
- 如果只想看指定目录中的子目录列表,并不想看到其中的文件内容,可以使用
ls -d ,如下图
3.6 处理文件
3.6.1 touch 命令创建文件
- 使用
touch fileName 命令可以创建一个空文件,如下图- 创建文件的同时,将当前执行命令的用户作为文件的属主
-
可以看到文件的大小是 0 字节,说明文件是空的
3.6.1.1 touch 命令创建同名文件
-
如果在相同目录创建同名文件,只会改变文件的修改时间,如下图
3.6.1.2 touch 命令修改文件访问时间
- 如果不想改变文件的修改时间,只想改变文件的访问时间,可以使用
touch -a example.txt ,如下图-
ls -l 命令默认不显示文件的访问时间,而是显示修改时间 - 如果想要显示访问时间,需要使用
ls -l --time=atime -
该命令实测在 macOS 中不支持,下图中的环境为 CentOS
-
-
3.6.2 cp 命令复制文件
-
cp sourceName targetName 命令可以将原文件从当前位置复制到另一个位置,如下图-
cp example.txt example1.txt 是将example.txt 复制到当前目录,并改名为example1.txt - 可以看到
example1.txt 的修改日期与example.txt 不一致
-
3.6.2.1 cp 命令复制文件到其他目录
- 如果要将原文件复制到其他目录,只需要在目标文件名之前带上目录名即可,如下图
-
目录名可以是相对路径或绝对路径,下图中是相对路径
-
3.6.2.2 cp -i 命令复制文件并防止覆盖
- 如果复制文件的目标路径已经存在同名文件,默认会直接复制
- 为了防止误操作,可以使用
cp -i sourceName targetName ,这样如果目标路径存在同名文件就会给予提示,如下图- 可以看到在执行复制操作之前,
child3 目录中已经存在example.txt - 但是执行
cp example.txt child3/example.txt 还是成功的,并且child3 目录中的example.txt 修改时间产生变化 - 说明
child3/exmaple.txt 之前的文件已经被覆盖 - 但执行
cp -i example.txt child3/example.txt 时,系统给出了是否覆盖的提示,输入 n 则表明不覆盖,输入 y 表明覆盖
- 可以看到在执行复制操作之前,
3.6.2.3 单点符号在 cp 命令中的妙用
- 如果要从其他目录复制文件到当前目录,使用单点符号可以让命令变的更简洁,如下图
-
直接用单点符号表示当前目录,就可以直接将原目录的文件复制到当前目录
-
3.6.2.4 cp -R 命令实现递归复制目录
-
cp -R sourceName targetName 可以在复制目录时,将原目录的所有内容都递归复制到新目录,如下图- 可以看到,执行
cp child1 child3 后,系统抛出错误,表明child1 是目录,不能复制 - 但使用
cp -R child1 child3 后,复制成功,不仅在当前目录创建了child3 目录,并且该目录中拥有和child1 完全一致的内容
- 可以看到,执行
3.6.2.5 cp 命令使用通配符实现模糊复制
- 前文中在
ls 命令中使用的通配符,在cp 命令中也可以使用,如下图
3.6.3 Tab 制表符键自动补全
- 在输入文件名或目录名时,按一下制表符键,系统直接将该目录下唯一与当前输入内容的相匹配的名称补全
- 该功能无法掩饰,所以没有图
3.6.3.1 Tab 制表符键自动补全扩展
- 如果在按下制表符键时,系统无法找到唯一与当前输入内容匹配的名称,而是找到了多个,则会在命令下方将这些待选项全部列出,如下图
-
第一次时需要按两下 Tab 键
-
3.6.4 ln 链接文件
- 如果要在系统上维护同一个文件的两个甚至多个副本,除了保存多份物理文件副本之外,还可以采用 一个物理文件链接多个虚拟副本 的办法,这种操作被称为 链接文件
- 在 Linux 中有两种不同类型的文件链接方式
- 符号链接
- 硬链接
- 默认的创建方式就是硬链接,如下图
- 可以看到
example.txt 和example1.txt 不论是 inode 编号、文件大小、修改时间,都是一样的 - 因为硬链接创建的文件,从根本上来说就是同一个文件 、 引用硬链接文件相当于引用原文件
- 可以看到
3.6.4.1 ln -s 创建符号链接
- 使用
ln -s sourceName targetName 可以为原文件创建一个符号链接的文件副本,如下图- 可以看到,
example1.txt 和example.txt 不论是 inode 编号、文件大小、修改时间,都不一样 - 同时在
example1.txt 文件名后面通过一个箭头指向了example.txt ,表示该文件是example.txt 的链接文件
- 可以看到,
- 需要注意的是,不要创建链接文件的链接 ,这会导致文件之间形成混乱的链接链,不易于维护
3.6.5 mv 命令移动 / 重命名文件
- 在 Linux 中,通过
mv 命令可以实现对文件的重命名,但这种方式被称为移动,如下图-
实际上 Linux 中没有单纯意义的重命名操作,这种移动操作更类似于 Windows 的剪切操作
-
3.6.5.1 mv 命令实现重命名文件
- 使用
mv sourceName targetName 命令可以将原文件从当前目录移动到另一个目录,如下图- 如果是将原文件移动到当前目录,就可以实现重命名操作
- 如果将目标文件的路径和新文件名同时指定,也可以实现重命名操作
- 需要注意的是 ,对文件进行移动或重命名操作时,只会改变文件路径或名称,不会改变该文件的 inode 编号,这说明这个文件不论移动 / 重命名多少次,依旧是一开始的那个文件
- 可以看到
example.txt ,一路经过改名、移动并改名,其 inode 编号始终是 28841622
3.6.5.2 mv -i 命令移动文件并防止覆盖
- 如果在移动文件时,目标路径的文件已存在,原文件就会直接将目标文件覆盖,如下图
-
child1/example2.txt 之前的 inode 编号是 28841622 - 在执行移动操作后,
child1/example2.txt 的 inode 编号变成了 28842375 ,与之前的example.txt 保持一致 -
这说明之前的文件已经被覆盖了
-
- 为了防止文件被直接覆盖,可以使用
mv -i ,当出现需要覆盖的情况时,系统会给予提示,如下图
3.6.5.3 mv 命令移动目录
- 使用
mv 命令移动目录不需要添加任何指令,直接移动即可,如下图
3.6.6 rm 命令删除文件
- 使用
rm fileName 可以直接删除文件,如下图
3.6.6.1 rm -i 命令删除文件并确认操作
- 使用
rm -i fileName 可以在删除文件时,增加一个确认操作,如下图- 需要注意的是 ,Linux 中没有回收站,文件一旦删除,就无法找回,所以在删除时添加确认操作非常有必要
3.7 处理目录
3.7.1 mkdir 命令创建目录
- 使用
mkdir directoryName 可以创建一个空目录,如下图
3.7.1.1 mkdir -p 递归创建目录
- 使用
mkdir -p directoryName/directoryName1 可以创建一整串目录,如下图- 可以看到,不加
-p 指令时,无法直接创建多级目录,增加后就可以一次性加多级目录全部创建成功
- 可以看到,不加
3.7.2 删除目录
- 使用
rmdir directoryName 可以直接删除目录,如下图
3.7.2.1 rm -r 删除多级目录
- 看到这里肯定会奇怪,为什么突然又讲到
rm 命令了 - 因为
rmdir 命令只能删除空目录,并且无法通过增加指令的方式实现删除非空目录 - 想要删除非空目录,需要使用
rm -r directoryName 来实现,如下图- 可以看到,当试图使用
rmdir 删除非空的child1 目录时,系统给出了失败的提示 - 但是使用
rm -r 则删除成功
- 可以看到,当试图使用
3.7.2.2 rm -rf 及其危险的强制目录删除方式
- 一口气删除目录即其所有子目录和内容的终极大法是使用
rm -rf directoryName - 这个命令 既没有警告信息 ,也没有声音提示 ,所以这是一个非常危险的工具
- 如果你正好在拥有超级权限的 root 用户上使用这个命令,很可能会导致你的系统一去不复返
- 例如在根目录执行
rm -rf * ,有兴趣的可以创建一个虚拟机试试
- 例如在根目录执行
3.8 查看文件内容
3.8.1 file 命令查看文件类型
- 使用
file fileName 可以查看指定文件的文件类型,如下图- 下图中直接通过模糊匹配查出了当前目录下所有文件的文件类型
- 并且拥有相同文件后缀的文件查看出了不同的结果,这说明
file 命令不是简单的通过文件后缀来判断文件类型 - 而是探测到文件的内部,并决定文件是什么类型
-
同时也可以查看是否为目录
3.8.2.1 file 命令查看文件链接类型
- 使用
file 命令查看文件类型时,如果该文件是链接文件,也会被标记出来,如下图-
下图中的展现环境是 CentOS ,在查看文件类型时可以显示该文件链接的具体文件
-
-
但 macOS 中查看文件类型时,不会显示该文件链接的具体文件
3.8.2 查看整个文件
3.8.2.1 cat 命令查看文件内容
- 使用
cat fileName 命令可以查看指定文件的文件内容,如下图- 下图中的展现环境是 CentOS ,因为 macOS 部分指令没有效果
-
cat 命令是一次性把文件的内容全部显示出来,如果文件内容过多,不推荐使用该命令 -
cat -n 命令会给文件内容添加行号 -
cat -b 命令在给文件内容添加行号时,会过滤掉空白行 -
cat -T 命令会将文件内容中的 Tab 制表符替换成^ 符号,macOS 此指令无效
3.8.2.2 more 命令查看文件内容
- 使用
more fileName 会按照分页的模式显示文件内容,如下图-
操作方式是标准的分页模式,空格键翻页,回车键逐行
-
3.8.3 查看部分文件
3.8.3.1 tail 命令查看文件末尾内容
- 使用
tail fileName 会查看文件最后 10 行的内容,如下图
3.8.3.2 tail -n 命名查看指定行数的文件末尾内容
- 使用
tail -n rowNumber fileName 可以查看文件末尾指定行数的内容,如下图- 该命令还可以简写为
tail -rowNumber fileName ,例如tail -15 example.md ,就表示查看末尾 15 行的内容
- 该命令还可以简写为
3.8.3.3 tail -f 命令监听文件末尾内容
- 使用
tail -f fileName 可以持续监听文件末尾的内容,如下图- 如果文件内容发生变化,会直接将新内容输出在当前窗口
- 可以看到,下图在执行完命令后,在最下方没有出现新的命令接收行,这表明当前命令并没有结束,而是出于持续监听状态
- 要停止监听操作,只需要按 Ctrl+C 即可
3.8.3.4 head 命令查看文件头部内容
- 使用
head fileName 会查看文件头部的 10 行内容,如下图
3.8.3.5 head -n 命令查看指定行数的文件头部内容
- 使用
head -n rowNumber fileName 可以查看文件头部指定行数的内容,如下图- 该命令还可以简写为
head -rowNumber fileName ,例如head -15 example.md ,就表示查看头部 15 行的内容
- 该命令还可以简写为
3.9 小结
- 使用
cd 命令实现目录切换 - 使用
ls 命令查看文件目录 - 使用
touch 命令创建空文件、变更文件访问 / 修改时间 - 使用
cp 命令复制文件 - 使用
ln 命令制杖链接文件 - 使用
mv 命令重命名 / 移动文件 - 使用
rm 命令删除文件或目录 - 使用
mkdir 创建目录 - 使用
rmdir 删除空目录 - 使用
cat 查看文件所有内容 - 使用
more 分页查看文件内容 - 使用
less 增强分页查看文件内容 - 使用
tail 查看、监听文件末尾内容 - 使用
head 查看文件头部内容