跳至内容

面向 Linux 用户的高级命令

掌握基本命令后,高级命令可以在更专业的场景中提供更大的自定义和控制能力。


目标:在本章中,未来的 Linux 管理员将学到

✔ 上一章未涵盖的一些有用命令。
✔ 一些高级命令。

🏁 用户命令Linux

知识⭐
复杂性: ⭐ ⭐ ⭐

阅读时间: 20 分钟


uniq 命令

uniq 命令是一个非常强大的命令,尤其与 sort 命令配合使用时,对于日志文件分析非常有用。它允许您通过删除重复项来排序和显示条目。

为了说明 uniq 命令的工作原理,让我们使用一个名为 firstnames.txt 的文件,其中包含一个名字列表。

antoine
xavier
steven
patrick
xavier
antoine
antoine
steven

注意

uniq 要求输入文件在运行前必须是已排序的,因为它只比较连续的行。

在没有参数的情况下,uniq 命令不会显示 firstnames.txt 文件中连续相同的行。

$ sort firstnames.txt | uniq
antoine
patrick
steven
xavier

要仅显示只出现一次的行,请使用 -u 选项。

$ sort firstnames.txt | uniq -u
patrick

反之,要仅显示文件中至少出现两次的行,请使用 -d 选项。

$ sort firstnames.txt | uniq -d
antoine
steven
xavier

要简单地删除只出现一次的行,请使用 -D 选项。

$ sort firstnames.txt | uniq -D
antoine
antoine
antoine
steven
steven
xavier
xavier

最后,要计算每行出现的次数,请使用 -c 选项。

$ sort firstnames.txt | uniq -c
      3 antoine
      1 patrick
      2 steven
      2 xavier
$ sort firstnames.txt | uniq -cd
      3 antoine
      2 steven
      2 xavier

xargs 命令

xargs 命令允许从标准输入构建和执行命令。

xargs 命令从标准输入读取由空格或换行符分隔的参数,并使用初始参数加上从标准输入读取的参数来执行命令(默认为 /bin/echo)一次或多次。

第一个也是最简单的例子如下:

$ xargs
use
of
xargs
<CTRL+D>
use of xargs

xargs 命令等待来自标准 stdin 输入。输入了三行。用户输入结束由按键组合 Ctrl+D 指定给 xargsxargs 然后执行默认命令 echo,后面跟着对应用户输入的三个参数,即:

$ echo "use" "of" "xargs"
use of xargs

可以为 xargs 指定要运行的命令。

在以下示例中,xargs 将在标准输入指定的文件夹集合上运行 ls -ld 命令。

$ xargs ls -ld
/home
/tmp
/root
<CTRL+D>
drwxr-xr-x. 9 root root 4096  5 avril 11:10 /home
dr-xr-x---. 2 root root 4096  5 avril 15:52 /root
drwxrwxrwt. 3 root root 4096  6 avril 10:25 /tmp

实际上,xargs 命令执行了 ls -ld /home /tmp /root 命令。

如果被执行的命令不接受多个参数,比如 find 命令,会发生什么?

$ xargs find /var/log -name
*.old
*.log
find: paths must precede expression: *.log

xargs 命令尝试使用 -name 选项后面的多个参数来执行 find 命令,这导致 find 生成错误。

$ find /var/log -name "*.old" "*.log"
find: paths must precede expression: *.log

在这种情况下,必须强制 xargs 命令多次执行 find 命令(每次处理一行标准输入)。-L 选项后跟一个整数,可以指定一次处理命令的最大条目数。

$ xargs -L 1 find /var/log -name
*.old
/var/log/dmesg.old
*.log
/var/log/boot.log
/var/log/anaconda.yum.log
/var/log/anaconda.storage.log
/var/log/anaconda.log
/var/log/yum.log
/var/log/audit/audit.log
/var/log/anaconda.ifcfg.log
/var/log/dracut.log
/var/log/anaconda.program.log
<CTRL+D>

要将同一行上的两个参数指定为一次处理,请使用 -n 1 选项。

$ xargs -n 1 find /var/log -name
*.old *.log
/var/log/dmesg.old
/var/log/boot.log
/var/log/anaconda.yum.log
/var/log/anaconda.storage.log
/var/log/anaconda.log
/var/log/yum.log
/var/log/audit/audit.log
/var/log/anaconda.ifcfg.log
/var/log/dracut.log
/var/log/anaconda.program.log
<CTRL+D>

基于搜索的备份案例研究(使用 tar

$ find /var/log/ -name "*.log" -mtime -1 | xargs tar cvfP /root/log.tar
$ tar tvfP /root/log.tar
-rw-r--r-- root/root      1720 2017-04-05 15:43 /var/log/boot.log
-rw-r--r-- root/root    499270 2017-04-06 11:01 /var/log/audit/audit.log

xargs 命令的特殊之处在于它将输入参数放在被调用命令的末尾。这对于上面的例子来说效果很好,因为传入的文件将构成添加到存档中的文件列表。

使用 cp 命令的示例,将文件列表复制到目录中,这个文件列表将添加到命令的末尾……但是 cp 命令期望在命令末尾的是目标。为此,请使用 -I 选项将输入参数放在行的其他位置。

find /var/log -type f -name "*.log" | xargs -I % cp % /root/backup

-I 选项允许您指定一个字符(在上例中为 % 字符),xargs 的输入文件将放在此处。

yum-utils

yum-utils 包是一系列由不同作者为 yum 构建的实用工具,它们使 yum 的使用更加轻松和强大。

注意

虽然在 Rocky Linux 8 中 yum 已被 dnf 取代,但包名仍然是 yum-utils,尽管它也可以安装为 dnf-utils。这些是经典的 YUM 实用程序,作为 DNF 之上的 CLI 包装器实现,以保持与 yum-3 的向后兼容性。

以下是一些这些实用程序的示例。

repoquery 命令

repoquery 命令用于查询存储库中的软件包。

使用示例

  • 显示软件包的依赖项(可以是已安装或未安装的软件包),等同于 dnf deplist <package-name>
repoquery --requires <package-name>
  • 显示已安装软件包提供的文件(未安装的软件包无效),等同于 rpm -ql <package-name>
$ repoquery -l yum-utils
/etc/bash_completion.d
/etc/bash_completion.d/yum-utils.bash
/usr/bin/debuginfo-install
/usr/bin/find-repos-of-install
/usr/bin/needs-restarting
/usr/bin/package-cleanup
/usr/bin/repo-graph
/usr/bin/repo-rss
/usr/bin/repoclosure
/usr/bin/repodiff
/usr/bin/repomanage
/usr/bin/repoquery
/usr/bin/reposync
/usr/bin/repotrack
/usr/bin/show-changed-rco
/usr/bin/show-installed
/usr/bin/verifytree
/usr/bin/yum-builddep
/usr/bin/yum-config-manager
/usr/bin/yum-debug-dump
/usr/bin/yum-debug-restore
/usr/bin/yum-groups-manager
/usr/bin/yumdownloader
…

yumdownloader 命令

yumdownloader 命令从存储库下载 RPM 软件包。等同于 dnf download --downloadonly --downloaddir ./ package-name

注意

此命令对于快速构建少量 RPM 的本地存储库非常有用!

示例:yumdownloader 将下载 samba RPM 软件包及其所有依赖项。

$ yumdownloader --destdir /var/tmp --resolve samba
or
$ dnf download --downloadonly --downloaddir /var/tmp  --resolve  samba
选项 注释
--destdir 下载的软件包将存储在指定的文件夹中。
--resolve 也下载软件包依赖项。

psmisc

psmisc 包包含用于管理系统进程的实用程序。

  • pstreepstree 命令以树状结构显示系统上的当前进程。
  • killallkillall 命令向所有具有指定名称的进程发送终止信号。
  • fuserfuser 命令识别使用指定文件或文件系统的进程的 PID

示例

$ pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─agetty
        ├─auditd───{auditd}
        ├─crond
        ├─dbus-daemon───{dbus-daemon}
        ├─firewalld───{firewalld}
        ├─lvmetad
        ├─master─┬─pickup
                └─qmgr
        ├─polkitd───5*[{polkitd}]
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        └─tuned───4*[{tuned}]
# killall httpd

终止访问 /etc/httpd/conf/httpd.conf 文件的进程(使用 -k 选项)。

# fuser -k /etc/httpd/conf/httpd.conf

watch 命令

watch 命令定期执行一个命令并在终端全屏显示结果。

-n 选项允许您指定命令每次执行之间的秒数。

注意

要退出 watch 命令,您必须输入按键:Ctrl+C 来终止进程。

示例

  • 每 5 秒显示一次 /etc/passwd 文件的末尾。
watch -n 5 tail -n 3 /etc/passwd

结果

Every 5.0s: tail -n 3 /etc/passwd                                                                                                                                rockstar.rockylinux.lan: Thu Jul  1 15:43:59 2021

sssd:x:996:993:User for sssd:/:/sbin/nologin
chrony:x:995:992::/var/lib/chrony:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
  • 监控文件夹中的文件数量。
watch -n 1 'ls -l | wc -l'
  • 显示时钟。
watch -t -n 1 date

install 命令

与它的名字可能暗示的相反,install 命令不用于安装新软件包。

此命令结合了文件复制(cp)和目录创建(mkdir),并带有权限管理(chmodchown)和其他有用的功能(如备份)。

install source dest
install -t directory source [...]
install -d directory

选项

选项 备注                          
-b--backup[=suffix] 创建目标文件的备份。
-d     将参数视为目录名              
-D     在复制 SOURCE 到 DEST 之前创建所有父目录。
-g-o     设置所有者              
-m     设置权限              
-p     保留源文件的修改时间          
-t 将所有源参数复制到目录。

注意

有用于管理 SELinux 上下文的选项(请参阅手册页)。

示例

使用 -d 选项创建目录。

install -d ~/samples

将文件从源位置复制到目录。

install src/sample.txt ~/samples/

这两条命令可以用一条命令完成。

$ install -v -D -t ~/samples/ src/sample.txt
install: creating directory '~/samples'
'src/sample.txt' -> '~/samples/sample.txt'

此命令已节省时间。将其与所有者、所属组和权限管理结合使用,以节省更多时间。

sudo install -v -o rocky -g users -m 644 -D -t ~/samples/ src/sample.txt

注意

在这种情况下,需要 sudo 才能更改所有权。

您也可以使用 -b 选项创建现有文件的备份。

$ install -v -b -D -t ~/samples/ src/sample.txt
'src/sample.txt' -> '~/samples/sample.txt' (archive: '~/samples/sample.txt~')

如您所见,install 命令会创建一个备份文件,并在原始文件名后附加一个 ~ 符号。

可以使用 -S 选项指定后缀。

$ install -v -b -S ".bak" -D -t ~/samples/ src/sample.txt
'src/sample.txt' -> '~/samples/sample.txt' (archive: '~/samples/sample.txt.bak')

tree 命令

以树状方式展开目录中的文件或目录。

选项 描述
-a 列出所有文件。
-h 以更易读的方式打印大小。
-u 显示文件所有者或 UID 号。
-g 显示文件所属组或 GID 号。
-p 打印每个文件的权限。

例如

$ tree -hugp /etc/yum.repos.d/
/etc/yum.repos.d/
├── [-rw-r--r-- root     root      1.6K]  epel-modular.repo
├── [-rw-r--r-- root     root      1.3K]  epel.repo
├── [-rw-r--r-- root     root      1.7K]  epel-testing-modular.repo
├── [-rw-r--r-- root     root      1.4K]  epel-testing.repo
├── [-rw-r--r-- root     root       710]  Rocky-AppStream.repo
├── [-rw-r--r-- root     root       695]  Rocky-BaseOS.repo
├── [-rw-r--r-- root     root      1.7K]  Rocky-Debuginfo.repo
├── [-rw-r--r-- root     root       360]  Rocky-Devel.repo
├── [-rw-r--r-- root     root       695]  Rocky-Extras.repo
├── [-rw-r--r-- root     root       731]  Rocky-HighAvailability.repo
├── [-rw-r--r-- root     root       680]  Rocky-Media.repo
├── [-rw-r--r-- root     root       680]  Rocky-NFV.repo
├── [-rw-r--r-- root     root       690]  Rocky-Plus.repo
├── [-rw-r--r-- root     root       715]  Rocky-PowerTools.repo
├── [-rw-r--r-- root     root       746]  Rocky-ResilientStorage.repo
├── [-rw-r--r-- root     root       681]  Rocky-RT.repo
└── [-rw-r--r-- root     root      2.3K]  Rocky-Sources.repo

0 directories, 17 files

stat 命令

stat 命令显示文件或文件系统的状态。

$ stat /root/anaconda-ks.cfg
  File: /root/anaconda-ks.cfg
  Size: 1352            Blocks: 8          IO Block: 4096   regular file
Device: 10302h/66306d   Inode: 2757097     Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-01-20 13:04:57.012033583 +0800
Modify: 2023-09-25 14:04:48.524760784 +0800
Change: 2024-01-24 16:37:34.315995221 +0800
 Birth: 2
  • File - 显示文件的路径位置。
  • Size - 以字节为单位显示文件大小。如果这是一个目录,它显示目录名称占用的固定 4096 字节。
  • Blocks - 显示分配的块数。注意!此命令中每个块的大小为 512 字节。ls -ls 中每个块的默认大小为 1024 字节。
  • Device - 设备编号,以十进制或十六进制表示。
  • Inode - Inode 是 Linux 内核分配给文件或目录的唯一 ID 号。
  • Links - 硬链接的数量。硬链接有时也称为物理链接。
  • Access - 文件和目录的最后访问时间,即 GNU/Linux 中的 atime
  • Modify - 文件和目录的最后修改时间,即 GNU/Linux 中的 mtime
  • Change - 属性最后更改的时间,即 GNU/Linux 中的 ctime
  • Birth - 创建时间(Birth time)。在一些文档中,它被缩写为 btimecrtime。您需要文件系统和内核版本高于某个版本才能显示创建时间。

对于文件

atime - 在使用 catlessmorehead 等命令访问文件内容后,文件的 atime 可能会更新。请注意!文件的 atime 不是实时更新的,出于性能考虑,需要等待一段时间才能显示。mtime - 修改文件内容可以更新文件的 mtime(例如,通过重定向追加或覆盖文件内容),因为文件大小是文件的属性,所以 ctime 也会同时更新。ctime - 更改文件的所有者、组、权限、文件大小和链接(软链接和硬链接)会更新 ctime。

对于目录

atime - 在使用 cd 命令进入一个从未访问过的目录后,您可以更新和固定该目录的 atimemtime - 在此目录中执行创建、删除和重命名文件等操作会更新目录的 mtimectimectime - 当目录的权限、所有者、组等发生变化时,目录的 ctime 会更新。

技巧

  • 如果您创建了一个新文件或目录,它的 atimemtimectime 将完全相同。
  • 如果修改了文件内容,文件的 mtimectime 必然会更新。
  • 如果在目录中创建了一个全新的文件,那么该目录的 atimectimemtime 将同时更新。
  • 如果目录的 mtime 被更新,那么该目录的 ctime 也必然会更新。