Bash 是用于管理 Linux 计算机的重要工具。 此名称是 Bourne Again Shell 的缩写
Shell 是命令操作系统执行操作的程序。 可以在计算机的控制台中输入命令,然后直接运行命令,也可以使用脚本运行批量命令。 PowerShell 和 Bash 等 Shell 为系统管理员提供了对其所负责的计算机进行优化控制所需的功能和精度。
Bash 基础知识
若要了解 Bash,首先要了解 Bash 语法。 了解语法后,可以将其应用到你运行的每个 Bash 命令
Bash 命令的完整语法如下:
1 | bash复制代码command [options] [arguments] |
Bash 将其遇到的第一个字符串视为命令。 以下命令使用 Bash 的 ls
(表示“list”)命令显示当前工作目录的内容:
1 | bash复制代码ls |
Bash 命令通常带有参数。 例如,可以在 ls
命令中添加路径名称,以列出其他目录的内容:
1 | bash复制代码ls /etc |
大多数 Bash 命令都具有用于修改其工作方式的选项。 选项(也称为标志)为命令传达更具体的指令。 例如,名称以句点开头的文件和目录会对用户隐藏,而不会由 ls
显示。 但可以在 ls
命令中添加 -a
(表示“all”)标志,以便查看目标目录中的所有内容:
1 | bash复制代码ls -a /etc |
甚至可以为了简洁合并标志。 例如,与其输入 ls -a -l /etc
以长格式显示 Linux 的 /etc 目录中的所有文件和目录,不如输入以下内容:
1 | bash复制代码ls -al /etc |
Bash 非常简洁。 有时使用一个命令即可完成大量任务(这是 Bash 爱好者引以为豪之处)
获取帮助
可以使用或必须使用的选项和参数因命令而异。 幸运的是,Bash 文档内置到了操作系统中。 只需要使用一个命令即可获得所需帮助。 若要了解命令的选项,请使用 man
(表示“manual”)命令。 例如,若要查看 mkdir
(表示“make directory”)命令的所有选项,请执行以下操作:
1 | arduino复制代码man mkdir |
man
有助于你了解 Bash。 man
可用于获取了解命令工作方式所需的信息。
大多数 Bash 和 Linux 命令都支持 --help
选项。 这会显示命令的语法和选项的说明。 为进行演示,请输入 mkdir --help
以这种方式获取的帮助通常比使用 man
获取的帮助更简洁。
使用通配符
通配符是表示 Bash 命令中的一个或多个字符的符号。 最常用的通配符是星号。 它表示无字符或字符序列。 假设当前目录中包含数百个图像文件,但你只想查看文件名以 .png 结尾的 PNG 文件。 以下命令仅列出上述文件:
1 | bash复制代码ls *.png |
备注
与其他操作系统不同,Linux 对于文件扩展名并没有正式概念。 这不表示 PNG 文件没有 .png 扩展名。 这只是表示 Linux 不会对文件名以 .png 结尾这一点附加任何特殊意义。
现在,假设当前目录中还包含 JPEG 文件。 一些文件以 .jpg 结尾,而其他文件以 .jpeg 结尾。 以下是列出所有 JPEG 文件的一种方法:
1 | bash复制代码ls *.jpg *.jpeg |
以下是另一种方法:
1 | bash复制代码ls *.jp*g |
*
通配符与零字符或多字符匹配,但 ?
通配符表示单字符。 如果当前目录中包含名为 0001.jpg、0002.jpg 以此类推到 0009.jpg 的文件,以下命令会将其全部列出:
1 | bash复制代码ls 000?.jpg |
但使用通配符筛选输出的另一种方法是使用表示字符组的方括号。 以下命令会列出当前目录中名称包含句点且句点后跟小写 J 或 P 的所有文件。该命令会列出所有 .jpg、.jpeg 和 .png 文件,但不会列出 .gif 文件:
1 | bash复制代码ls *.[jp]* |
在 Linux 中,文件名和对文件名进行操作的命令区分大小写。 因此,若要列出当前目录中名称包含句点且句点后跟大写或小写 J 或 P 的所有文件,可以输入以下内容:
1 | bash复制代码ls *.[jpJP]* |
方括号中的表达式可以表示字符范围。 例如,以下命令会列出当前目录中名称以小写字母开头的所有文件:
1 | bash复制代码ls [a-z]* |
相反,以下命令会列出当前目录中名称以大写字母开头的所有文件:
1 | bash复制代码ls [A-Z]* |
以下命令则会列出当前目录中名称以大写字母或小写字母开头的所有文件:
1 | bash复制代码ls [a-zA-Z]* |
如果需要将某个通配符用作普通字符,可以在该字符前加上一个反斜杠,使其成为文本或将其“转义”。 因此,如果由于某种原因在文件名中使用了星号(不应故意执行此操作),可以使用如下命令进行搜索:
1 | shell复制代码$ ls *** |
Bash 命令和运算符
ls
命令
ls
列出当前目录中的内容或命令参数所指定目录中的内容。 它本身会列出当前目录中的文件和目录:
1 | bash复制代码ls |
名称以句点开头的文件和目录默认隐藏。 若要在目录列表中添加这些项,请使用 -a
标志:
1 | bash复制代码ls -a |
若要详细了解当前目录中的文件和目录,请使用 -l
标志:
1 | bash复制代码ls -l |
cat
命令
假设要查看文件中的内容。 可以使用 cat
命令进行查看。 文件是文本文件时,输出才有意义。 以下命令显示存储在 /etc 目录中的 os-release 文件的内容:
1 | bash复制代码cat /etc/os-release |
此命令有用,因为它会告诉你正在运行哪个 Linux 分发版:
1 | ini复制代码NAME="Ubuntu" |
/etc 目录是 Linux 中的一种特殊目录。 它包含系统配置文件。 不建议删除此目录中的任何文件,除非你了解要执行的操作。
sudo
命令
某些 Bash 命令只能由根用户(系统管理员或超级用户)运行。 如果在权限不足的情况下尝试其中一个命令,该命令会失败。 例如,只有以超级用户身份登录的用户才可以使用 cat
显示 /etc/at.deny 的内容:
1 | bash复制代码cat /etc/at.deny |
at.deny 是一个特殊文件,用于确定可使用其他 Bash 命令提交作业以供后续执行的用户。
不建议在大部分时间内以根身份运行。 太过危险。 若要在不以超级用户身份登录的情况下运行需要管理员权限的命令,请在命令前加上 sudo
:
1 | bash复制代码sudo cat /etc/at.deny |
sudo
表示“superuser do”。 你使用它时,shell 知道对于此命令而言,你具有根用户级别的权限。
cd
、mkdir
和 rmdir
命令
cd
表示“change directory”,其功能也恰如其名:将当前目录更改为其他目录。 与 Windows 中的对应命令相同,它可实现从一个目录到另一个目录的移动。 使用以下命令将移动到名为 orders 的当前目录的子目录:
1 | bash复制代码cd orders |
可以通过将 ..
指定为目录名称来向上移动目录:
1 | bash复制代码cd .. |
使用此命令将移动到主目录,即首次登录时所访问的目录:
1 | bash复制代码cd ~ |
可以使用 mkdir
命令创建目录。 以下命令会在当前的工作目录中创建名为 orders 的子目录:
1 | arduino复制代码mkdir orders |
如果要使用一个命令创建子目录及其所属子目录,请使用 --parents
标志:
1 | arduino复制代码mkdir --parents orders/2019 |
rmdir
命令可以删除目录,前提是目录不为空。 幸运的是,可以使用 rm
命令删除不为空的目录。
rm
命令
rm
命令是“remove”的缩写。 如你所料,rm
可以删除文件。 因此,此命令可以删除 0001.jpg:
1 | bash复制代码rm 0001.jpg |
此命令可以删除当前目录中的所有文件:
1 | bash复制代码rm * |
请谨慎使用 rm
。 此命令太过危险。
运行带有 -i
标志的 rm
可以让你在删除之前有考虑时间:
1 | bash复制代码rm -i * |
养成在每个 rm
命令中添加 -i
的习惯,避免造成 Linux 中的重大误操作。 功能强大的 rm -rf /
命令可以删除整个驱动器上的所有文件。 其工作方式是递归删除根的所有子目录及其所属子目录。 -f
(表示“force”)标志会隐藏提示从而将问题复杂化。 请勿这样操作。
如果要删除名为 orders 且不为空的子目录,可以通过以下方式使用 rm
命令:
1 | bash复制代码rm -r orders |
这会删除 orders 子目录和其中的所有内容,包括其他子目录。
cp
命令
如果需要,cp
命令不仅可以复制文件,还可以复制整个目录(和子目录)。 若要创建名为 0002.jpg 的 0001.jpg 副本,请使用以下命令:
1 | yaml复制代码cp 0001.jpg 0002.jpg |
如果 0002.jpg 已存在,则 Bash 会在无提示情况下将其替换。 如果这是你所需的结果,这样做很好,但如果你没有意识到将要覆盖旧版本,就很糟糕。
幸运的是,如果使用 -i
(表示“interactive”)标志,Bash 会在删除现有文件之前发出警告。 以下命令更安全:
1 | yaml复制代码cp -i 0001.jpg 0002.jpg |
当然,可以使用通配符一次复制多个文件。 若要将当前目录中的所有文件复制到名为 photos 的子目录中,请使用以下命令:
1 | bash复制代码cp * photos |
若要将名为 photos 的子目录中的所有文件复制到名为 images 的子目录中,请使用以下命令:
1 | bash复制代码cp photos/* images |
此命令假定 images 目录已存在。 如果不存在,则可以创建该目录,然后使用以下命令复制 photos 目录的内容:
1 | bash复制代码cp -r photos images |
-r
表示“recursive”。 -r
标志的另一个优点是,如果 photos 包含自己的子目录,则子目录也会复制到 images 目录中。
ps
命令
ps
命令可以提供当前运行的所有进程的快照。 它本身不带参数,可显示所有 shell 进程,换言之,它无法显示太多进程。 但如果你添加 -e
标志,情况就会有所变化:
1 | 复制代码ps -e |
-e
会列出所有运行中的进程,通常数量很多。
若要更全面地了解系统中正在运行的进程,请使用 -ef
标志:
1 | 复制代码ps -ef |
此标志显示所有正在运行的进程的名称、其进程标识号 (PID)、其父进程的 PID (PPID) 及其开始时间 (STIME)。 还显示其连接到 (TTY) 的终端(如果有)、其占用的 CPU 时间 (TIME) 及其完整路径名。
另外,你可能会发现显示通过以下方式使用的 ps
的文档:
1 | 复制代码ps aux |
ps aux
和 ps -ef
是相同的。 这种双重性可追溯到 POSIX Unix 系统(Linux 属其中之一)与 BSD Unix 系统(最常见的是 macOS)之间的历史差异。 最初,POSIX 使用 -ef
,而 BSD 采用 aux
。 现在,两种操作系统系列都接受这两种格式。
这很好地提醒了你应仔细阅读相关手册,了解所有的 Linux 命令。 学习 Bash 如同学习第二语言英语。 规则存在很多例外。
w
命令
为查找出服务器上的用户,Linux 提供了 w
(表示“who”)命令。 它显示当前计算机系统上的用户及其活动相关的信息。 w
显示用户名、用户 IP 地址、用户登录时间、用户当前正在运行的进程及其运行时间。 它是系统管理员的重要工具。
Bash I/O 运算符
通过使用 Bash 命令及其许多选项可以在 Linux 中执行许多操作。 但你也可以在合并命令时使用以下 I/O 运算符执行这些操作:
<
,用于将输入重定向到键盘以外的源>
,用于将输出重定向到屏幕以外的目标>>
,用于执行相同的操作,但只是追加,并不进行覆盖|
,用于将一个命令的输出通过管道传输到另一个命令的输入
假设要列出当前目录中的所有内容,并捕获名为 list.txt 的文件中的输出。 以下命令可实现此操作:
1 | bash复制代码ls > listing.txt |
如果 listing.txt 已存在,它会被覆盖。 如果改用 >>
运算符,则 ls
的输出将追加到 listing.txt 的现有内容中:
1 | bash复制代码ls >> listing.txt |
管道运算符功能非常强大(且经常使用)。 它可以将第一个命令的输出重定向到第二个命令的输入。 假设使用 cat
显示大型文件的内容,但内容滚动过快,你无法阅读。 可以将结果管道传输给 more
等其他命令,使输出更易于管理。 以下命令列出所有当前正在运行的进程。 但屏幕填满后,输出会暂停显示,直到你选择“Enter”后才会显示下一行:
1 | 复制代码ps -ef | more |
还可以将输出管道传输到 head
,以查看前几行:
1 | bash复制代码ps -ef | head |
或者,假设要筛选输出,使其只包括含词“daemon”的行。 实现此目的的一种方法是将 ps
的输出管道传输到 Linux 的 grep
工具:
1 | perl复制代码ps -ef | grep daemon |
还可以将文件用作输入。 标准输入默认来自键盘,但也可以进行重定向。 若要从文件而不是键盘获取输入,请使用 <
运算符。 系统管理员的一项常见任务是对文件内容进行排序。 顾名思义,sort
会按字母顺序对文本进行排序:
1 | bash复制代码sort < file.txt |
若要将排序结果保存到新文件,可以重定向输入和输出:
1 | bash复制代码sort < file.txt > sorted_file.txt |
可以根据需要使用 I/O 运算符链接 Linux 命令。 请考虑以下命令:
1 | bash复制代码cat file.txt | fmt | pr | lpr |
cat
的输出转到 fmt
,fmt
的输出转到 pr
,依此类推。 fmt
将结果格式化为整齐段落。 pr
对结果进行分页处理。 lpr
将分页输出发送到打印机。 一行命令即可完成所有操作!
本文转载自: 掘金