实用命令
# 文件的复制移动
# cp 复制文件
复制文件的格式为:
$ cp source destination
当 source 和 destination 参数都是文件名时,cp 命令将源文件复制成一个新文件,并且以 destination 命名。新文件就像全新的文件一样,有新的修改时间。
如果目标文件已经存在,cp 命令并不会提醒这一点。最好是加上-i
选项,强制 shell 询问是否需要覆盖已有文件。
也可以将文件复制到现有目录中。
$ cp -i test_one /home/christine/Documents/
新文件就出现在目录 Documents 中了,和源文件同名。
==上面的例子在目标目录名尾部加上了一个正斜线(/),这表明 Documents 是目录而非文件。这有助于明确目的,而且在复制单个文件时非常重要。如果没有使用正斜线,子目录/home/christine/Documents 又不存在,就会有麻烦。在这种情况下,试图将一个文件复制到 Documents 子目录反而会创建一个名为 Documents 的文件,连错误消息都不会显示!==
上一个例子采用了绝对路径,不过也可以使用相对路径。
本章在前面介绍了特殊符号可以用在相对文件路径中。其中的单点符(.)就很适合用于 cp 命令。记住,单点符表示当前工作目录。如果需要将一个带有很长的源对象名的文件复制到当前工作目录中时,单点符能够简化该任务。如果你的源对象名很长,使用单点符要比输入完整的目标对象名省事得多。
$ cp -i /etc/NetworkManager/NetworkManager.conf .
==cp 命令的 -R 参数威力强大。可以用它在一条命令中递归地复制整个目录的内容:==
$ ls -Fd *Scripts #-d选项只列出目录本身的信息,不列出其中的内容。一般可与 l 选项搭配显示目录自身详情
$ cp -R Scripts/ Mod_Scripts
在执行 cp -R 命令之前,目录 Mod_Scripts 并不存在。它是随着 cp -R 命令被创建的,整个 Scripts 目录中的内容都被复制到其中。注意,在新的 Mod_Scripts 目录中,所有的文件都有对应的新日期。Mod_Scripts 目录现在已经成为了 Scripts 目录的完整副本。
也可以在 cp 命令中使用通配符:
$ cp *script Mod_Scripts/
该命令将所有以 script 结尾的文件复制到 Mod_Scripts 目录中。
# mv 移动/重命名文件
在 Linux 中,重命名文件称为移动(moving)。mv 命令可以将文件和目录移动到另一个位置或重新命名。
$ mv fall fzll #重命名
$ mv fzll Pictures/ #把文件fzll从/home/testuser移动到了/home/testuser/Pirctures
注意,mv 将文件名从 fall 更改为 fzll,但 inode 编号和时间戳保持不变。这是因为 mv 只影响文件名。 和 cp 命令类似,也可以在 mv 命令中使用-i
参数。这样在命令试图覆盖已有的文件时,你就会得到提示。
也可以使用 mv 命令移动文件位置并修改文件名称,这些操作只需一步就能完成:
$ mv /home/testuser/Pictures/fzll /home/testuser/fall
==也可以使用 mv 命令移动整个目录及其内容:==
$ mv Mod_Scripts Old_Scripts
# 文件的查看
可用 file 命令确定文件的文件类型。
$ file 1.txt
1.txt: ASCII text #file命令不仅能确定文件中包含的文本信息,还能确定该文本文件的字符编码,ASCII
常见的文件类型还有很多类型,比如下面几种
- directory 目录
- symbolic link to 'data_file' 符号链接
- Bourne-Again shell script,ASCII text executable 脚本文件
- /usr/bin/ls: ELF 64-bit LSB executable,x86-64,version 1 (SYSV),dynamically linked (uses shared libs),for GNU/Linux 2.6.24
二进制可执行程序。file 命令能够确定该程序编译时所面向的平台以及需要何种类型的库。如果你有从未知源处获得的二进制文件,这会是个非常有用的特性 - JSON data
知道如何查看文件类型后,接下来学习如何查看文件内容。几个常见的命令是 cat,more 与 less。more 命令目前已经和 less 一样支持上下翻页,基本没有区别了。对于查看单个完整文件,群主更偏向直接使用 vim 查看。
# tail 查看文件尾
==有时存在一些巨型文件,如有些日志文件可以达到几十 GB 之大,这时候如果还整体查看文件,可能直接把 vim 等程序卡死了。此时需要的就是查看部分文件。常用的命令为 tail 和 head。==
更常见的场景是查看文件的末尾,如日志的末尾,查看最新产生的内容。默认情况是查看此文件最后十行的内容。
$ tail log_file
可以向 tail 命令中加入-n 参数来修改所显示的行数。在下面的例子中,通过加入-n 2 使 tail 命令只显示文件的最后两行:
$ tail -n 2 log_file
**==-f 参数是 tail 命令的一个突出特性。它允许你在其他进程使用该文件时查看文件的内容。tail 命令会保持活动状态,并不断显示添加到文件中的内容。==**这是实时监测系统日志的绝妙方式。
# head 查看文件头
head 命令,顾名思义,会显示文件开头那些行的内容。默认情况下,它会显示文件前 10 行的文本。类似于 tail 命令,它也支持-n 参数,这样就可以指定想要显示的内容了。
==这两个命令都允许你在破折号后面直接输入想要显示的行数:==
$ head log_file
$ head -5 log_file
# 进程相关
当程序运行在系统上时,我们称之为进程(process)。想监测这些进程,需要熟悉 ps/top 等命令的用法。ps 命令好比工具中的瑞士军刀,它能输出运行在系统上的所有程序的许多信息。而 top 可以监控当前各个进程的运行状态,以及占用 cpu,内存等系统资源的情况。
# ps 查看进程
默认情况下,ps 命令只会显示运行在当前控制台下的属于当前用户的进程。直接执行 ps 命令,可以发现我们只运行了 bash shell(注意,shell 也只是运行在系统上的另一个程序而已)以及 ps 命令本身。可以看到基本输出显示了程序的进程 ID(Process ID,PID)、它们运行在哪个终端(TTY)以及进程已用的 CPU 时间。
Linux 系统中使用的 GNU ps 命令支持 3 种不同类型的命令行参数:
- Unix 风格的参数,前面加单破折线;Unix 风格的参数是从贝尔实验室开发的 AT&T Unix 系统上原有的 ps 命令继承下来的。
- BSD 风格的参数,前面不加破折线;伯克利软件发行版(Berkeley software distribution,BSD)是加州大学伯克利分校开发的一个 Unix 版本。它和 AT & T Unix 系统有许多细小的不同
- GNU 风格的长参数,前面加双破折线。
Unix 风格一些常用的参数组合:
$ ps -ef #查看系统上运行的所有进程 -e参数指定显示所有运行在系统上的进程;-f参数则扩展了输出,这些扩展的列包含了有用的信息。
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:29 ? 00:00:01 /sbin/init
...
- UID:启动这些进程的用户。
- PID:进程的进程 ID。
- PPID:父进程的进程号(如果该进程是由另一个进程启动的)。
- C:进程生命周期中的 CPU 利用率。
- STIME:进程启动时的系统时间。
- TTY:进程启动时的终端设备。
- TIME:运行进程需要的累计 CPU 时间。
- CMD:启动的程序名称。
如果想要获得更多的信息,可采用-l 参数,它会产生一个长格式输出。
$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 500 3081 3080 0 80 0 - 1173 wait pts/0 00:00:00 bash
0 R 500 4463 3081 1 80 0 - 1116 - pts/0 00:00:00 ps
注意使用了-l 参数之后多出的那些列。
- F:内核分配给进程的系统标记。1 代表 进程被 fork 但没有被执行。4 代表使用了超级管理员的权限。5 代表 1 和 4 都做了。0 没有任何特殊含义,含义为进程被 fork 了,也确实执行了,并且没有超级用户权限。
- S:进程的状态(S 代表在休眠;R 代表正在运行,或正等待运行;Z 代表僵化,进程已结束但父进程已不存在;T 代表停止,I 代表 idle 进程)。
- PRI:进程的优先级(越大的数字代表越低的优先级)。
- NI:谦让度值用来参与决定优先级。越大优先级越低。
- ADDR:进程的内存地址。正在运行的任务将在此列中显示一个破折号('-')
- SZ:所需物理内存页面的大致大小。详情看 vsz 与 rss
- WCHAN:进程休眠的内核函数的地址。
在使用 BSD 参数时,ps 命令会自动改变输出以模仿 BSD 格式。大部分的输出列跟使用 Unix 风格参数时的输出是一样的,只有一小部分不同。
$ ps l
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
0 500 3081 3080 20 0 4692 1432 wait Ss pts/0 0:00 -bash
0 500 5104 3081 20 0 4468 844 - R+ pts/0 0:00 ps l
- VSZ:进程的虚拟内存大小,以千字节(KB)为单位。
- RSS:常驻集大小,进程在未换出时占用的物理内存。
- STAT:代表当前进程状态的双字符状态码。
许多系统管理员都喜欢 BSD 风格的 l 参数。它能输出更详细的进程状态码(STAT 列)。双字符状态码能比 Unix 风格输出的单字符状态码更清楚地表示进程的当前状态。第一个字符采用了和 Unix 风格 S 列相同的值,表明进程是在休眠、运行还是等待。第二个参数进一步说明进程的状态。
- <:该进程运行在高优先级上。
- N:该进程运行在低优先级上。
- L:该进程有页面锁定在内存中。
- s:该进程是控制进程。
- l:该进程是多线程的。
- +:该进程运行在前台。
从前面的例子可以看出,bash 命令处于休眠状态,但同时它也是一个控制进程(在我的会话中,它是主要进程),而 ps 命令则运行在系统的前台。
最后,GNU 开发人员在这个新改进过的 ps 命令中加入了另外一些参数。其中一些 GNU 长参数复制了现有的 Unix 或 BSD 类型的参数,而另一些则提供了新功能。
可以将 GNU 长参数和 Unix 或 BSD 风格的参数混用来定制输出。GNU 长参数中一个着实让人喜爱的功能就是--forest 参数。它会显示进程的层级信息,并用 ASCII 字符绘出可爱的图表。这种格式让跟踪子进程和父进程变得十分容易。
# top 监控进程
ps 命令虽然在收集运行在系统上的进程信息时非常有用,但也有不足之处:它只能显示某个特定时间点的信息。如果想观察那些频繁换进换出的内存的进程趋势,用 ps 命令就不方便了。而 top 命令刚好适用这种情况。==top 命令跟 ps 命令相似,能够显示进程信息,但它是实时显示的。==
xbren@archlinux:~$ top
top - 00:01:04 up 38 min, 0 users, load average: 0.52, 0.58, 0.59
Tasks: 4 total, 1 running, 3 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.5 us, 0.8 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 16042.5 total, 8472.3 free, 7346.2 used, 224.0 buff/cache
MiB Swap: 49152.0 total, 49099.5 free, 52.5 used. 8565.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 9216 660 320 S 0.0 0.0 0:00.18 init
5115 root 20 0 9308 240 176 S 0.0 0.0 0:00.00 init
5116 xbren 20 0 19280 4808 4704 S 0.0 0.0 0:00.81 bash
5606 xbren 20 0 18920 2148 1528 R 0.0 0.0 0:00.04 top
输出的分上下两部分。第一部分显示的是系统的概况。第二部分显示了进程的实时概要信息。
第一部分的第一行显示了当前时间、系统的运行时间、登录的用户数以及系统的平均负载。平均负载有 3 个值:最近 1 分钟的、最近 5 分钟的和最近 15 分钟的平均负载。值越大说明系统的负载越高。由于进程短期的突发性活动,出现最近 1 分钟的高负载值也很常见,但如果近 15 分钟内的平均负载都很高,就说明系统可能有问题。
Linux 系统管理的要点在于定义究竟到什么程度才算是高负载。这个值取决于系统的硬件配置以及系统上通常运行的程序。对某个系统来说是高负载的值可能对另一系统来说就是正常值。在单核机器上,负载的意义是这样的,比如最近十五分钟的负载值为 5.09,含义为计算机的平均过载为 409%。平均而言,有 4.09 个进程在等待 CPU。通常对于单核机器来说,如果系统的负载值超过了 2,就说明系统比较繁忙了。但是对于多核机器来说,就不是这样计算的了。例如,如果在单 CPU 系统上的平均负载为 2,则意味着系统过载了 100%,在整个时间段内,一个进程正在使用 CPU,而另一个进程正在等待。在具有两个 CPU 的系统上,含义为两个不同的进程始终使用两个不同的 CPU。在具有四个 CPU 的系统上,这将代表只有 50%的使用率-两个进程使用两个 CPU,而两个 CPU 处于空闲状态。
第二行显示了进程概要信息——top 命令的输出中将进程叫作任务(task):有多少进程处在运行、休眠、停止或是僵化状态(僵化状态是指进程完成了,但父进程没有响应)。
下一行显示了 CPU 使用的概要信息。由前到后分别为:用户态使用率,内核态使用率,用做 nice 加权的进程分配的用户态 cpu 使用率,空闲的 cpu 使用率,等待磁盘写入完成时间比,硬件中断消耗时间,软件中断消耗时间,为处理其他进程而从虚拟机中偷走的 cpu 时间(仅虚拟机)。
紧跟其后的两行说明了系统内存的状态。第一行说的是系统的物理内存:总共有多少内存,还有多少空闲,当前用了多少,缓存占用了多少。后一行说的是同样的信息,不过是针对系统交换空间(如果分配了的话)的状态而言的。
第二部分显示了当前运行中的进程的详细列表,有些列跟 ps 命令的输出类似。给出一些未出现过的列的解释
- USER:进程属主的名字。
- PR:进程的优先级。
- NI:进程的谦让度值。
- VIRT:进程占用的虚拟内存总量。
- RES:进程占用的物理内存总量。
- SHR:进程和其他进程共享的内存总量。
- S:进程的状态(D 代表可中断的休眠状态,R 代表在运行状态,S 代表休眠状态,T 被任务控制信号终止的停止状态,t 代表被 debugger 在跟踪时终止的停止状态,Z 代表僵化状态,I 代表 idle 空闲)。
- %CPU:进程使用的 CPU 时间比例。
- %MEM:进程使用的内存占可用内存的比例。
- TIME+:自进程启动到目前为止的 CPU 时间总量。
- COMMAND:进程所对应的命令行名称,也就是启动的程序名
默认情况下,top 命令在启动时会按照 %CPU 值对进程排序。可以在 top 运行时使用多种交互命令重新排序。每个交互式命令都是单字符,在 top 命令运行时键入可改变 top 的行为。键入 f 允许你选择对输出进行排序的字段,键入 d 允许你修改轮询间隔。键入 q 可以退出 top。用户在 top 命令的输出上有很大的控制权。用这个工具就能经常找出占用系统大部分资源的罪魁祸首。当然了,一旦找到,下一步就是结束这些进程。这也正是接下来的话题。
# kill 发送信号
作为系统管理员,很重要的一个技能就是知道何时以及如何结束一个进程。有时进程挂起了,只需要动动手让进程重新运行或结束就行了。但有时,有的进程会耗尽 CPU 且不释放资源。在这两种情景下,你就需要能控制进程的命令。Linux 沿用了 Unix 进行进程间通信的方法。
在 Linux 中,进程之间通过信号来通信。进程的信号就是预定义好的一个消息,进程能识别它并决定忽略还是作出反应。进程如何处理信号是由开发人员通过编程来决定的。大多数编写完善的程序都能接收和处理标准 Unix 进程信号。这些信号列举如下。
信号 | 名称 | 描述 |
---|---|---|
1 | HUP | 挂起 |
2 | INT | 中断 |
3 | QUIT | 结束运行 |
9 | KILL | 无条件终止 |
11 | SEGV | 段错误 |
15 | TERM | 尽可能终止 |
17 | STOP | 无条件停止运行,但不终止 |
18 | TSTP | 停止或暂停,但继续在后台运行 |
19 | CONT | 在 STOP 或 TSTP 之后恢复执行 |
在 Linux 上有两个命令可以向运行中的进程发出进程信号。
kill 命令可通过进程 ID(PID)给进程发信号。默认情况下,kill 命令会向命令行中列出的全部 PID 发送一个 TERM 信号。遗憾的是,你只能用进程的 PID 而不能用命令名,所以 kill 命令有时并不好用。要发送进程信号,你必须是进程的属主或登录为 root 用户。否则会提示Operation not permitted
。
TERM 信号告诉进程可能的话就停止运行。不过,如果有不服管教的进程,那它通常会忽略这个请求。如果需要强制终止,可以指定广为人知的-9 参数,即 KILL 信号。
同时,-s 参数支持指定其他信号(用信号名或信号值)。
$ kill -s HUP 3940
要检查 kill 命令是否有效,可再运行 ps 或 top 命令,看看问题进程是否已停止。
第二个是 killall 命令,它非常强大,它支持通过进程名而不是 PID 来结束进程。killall 命令也支持通配符,这在系统因负载过大而变得很慢时很有用。
$ killall http*
上例中的命令结束了所有以 http 开头的进程,比如 Apache Web 服务器的 httpd 服务。 以 root 用户身份登录系统时,使用 killall 命令要特别小心,因为很容易就会误用通配符而结束了重要的系统进程。这可能会破坏文件系统。
# 磁盘相关
在 Linux 系统上有几个命令行命令可以用来帮助管理存储媒体。本节将介绍在日常系统管理中经常用到的核心命令。
# mount 挂载磁盘
Linux 文件系统将所有的磁盘都并入一个虚拟目录下。在使用新的存储媒体之前,需要把它放到虚拟目录下。这项工作称为==挂载(mounting)==。在今天的图形化桌面环境里,大多数 Linux 发行版都能自动挂载特定类型的可移动存储媒体。可移动存储媒体指的是可从 PC 上轻易移除的媒体,比如 CD-ROM、软盘和 U 盘。如果用的发行版不支持自动挂载和卸载可移动存储媒体,就必须手动完成。本节将介绍一些可以帮你管理可移动存储设备的 Linux 命令行命令。
Linux 上用来挂载媒体的命令叫作 mount。默认情况下,mount 命令会输出当前系统上挂载的设备列表。
$ mount
/dev/nvme0n1p1 on / type ext4 (rw,relatime)
/dev/nvme0n1p2 on /home type ext4 (rw,relatime)
/dev/nvme0n1p3 on /boot/EFI type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
/dev/sda1 on /run/media/testuser/My Ultra type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks2)
mount 命令提供如下四部分信息:
- 媒体的设备文件名
- 媒体挂载到虚拟目录的挂载点
- 文件系统类型
- 已挂载媒体的访问状态
上面例子的最后一行输出中,移动硬盘被 KDE 桌面自动挂载到了挂载点/run/media 下。这个移动硬盘本身是 NTFS 格式,但是显示为 fuseblk。fuse 意为 file system in user space,在 archlinux 下,需要使用 ntfs-3g 来识别 NTFS 硬盘。ntfs-3g 并不是内核模块,而是调用 fuse 来挂载的,所以 df -hT 以及 mount 的结果会认为是 fuseblk(blk=block)。
要手动在虚拟目录中挂载设备,需要以 root 用户身份登录,或是以 root 用户身份运行 sudo 命令。下面是手动挂载媒体设备的基本命令:
$ mount -t type device directory
type 参数指定了磁盘被格式化的文件系统类型。Linux 可以识别非常多的文件系统类型。如果是和 Windows PC 共用这些存储设备,通常得使用下列文件系统类型。
- vfat:Windows 长文件系统。缺点是单文件 4GB 的限制。
- ntfs:Windows NT、XP、Vista、Win 7 以及 Win10 中广泛使用的高级文件系统。
- iso9660:标准 CD-ROM 文件系统。
- exFAT:vfat 升级版,突破了 4GB 的限制。
大多数 U 盘和软盘会被格式化成 vfat/NTFS/exFAT 文件系统。而数据 CD 则必须使用 iso9660 文件系统类型。
后面两个参数定义了该存储设备的设备文件的位置以及挂载点在虚拟目录中的位置。比如说,手动将 U 盘/dev/sdb1 挂载到/media/disk,可用下面的命令:
$ sudo mount -t vfat /dev/sdb1 /media/disk
媒体设备挂载到了虚拟目录后,root 用户就有了对该设备的所有访问权限,而其他用户的访问则会被限制。你可以通过目录权限(后文将介绍权限)指定用户对设备的访问权限。
-o 参数允许在挂载文件系统时添加一些以逗号分隔的额外选项。以下为常用的选项。
- ro:以只读形式挂载。
- rw:以读写形式挂载。
- user:允许普通用户挂载文件系统。
- check=none:挂载文件系统时不进行完整性校验。
- loop:挂载一个文件。
从 Linux 系统上移除一个可移动设备时,不能直接从系统上移除,而应该先卸载。Linux 上不能直接弹出已挂载的 CD。如果你在从光驱中移除 CD 时遇到麻烦,通常是因为该 CD 还挂载在虚拟目录里。先卸载它,然后再去尝试弹出。
卸载设备的命令是 umount(是的,你没看错,命令名中并没有字母 n,这一点有时候很让人困惑)。umount 命令的格式非常简单:
umount [directory | device ]
umount 命令支持通过设备文件或者是挂载点来指定要卸载的设备。如果有任何程序正在使用设备上的文件,系统就不会允许你卸载它:
$ sudo umount: /home/rich/mnt
umount: /home/rich/mnt: device is busy
$ cd /home/rich
$ sudo umount /home/rich/mnt
$ ls -l mnt
total 0
上例中,命令行提示符仍然在挂载设备的文件系统目录中,所以 umount 命令无法卸载该镜像文件。一旦命令提示符移出该镜像文件的文件系统,umount 命令就能卸载该镜像文件。
如果在卸载设备时,系统提示设备繁忙,无法卸载设备,通常是有进程还在访问该设备或使用该设备上的文件。这时可用 lsof 命令获得使用它的进程信息,然后在应用中停止使用该设备或停止该进程。lsof 命令的用法很简单:lsof /path/to/device/node,或者 lsof /path/to/mount/point
# df 查看磁盘空间
有时你需要知道在某个设备上还有多少磁盘空间。df 命令可以让你很方便地查看所有已挂载磁盘的使用情况
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 18251068 7703964 9605024 45% /
/dev/sda1 101086 18680 77187 20% /boot
tmpfs 119536 0 119536 0% /dev/shm
/dev/sdb1 127462 113892 13570 90% /media/disk
df 命令会显示每个有数据的已挂载文件系统。如你在前例中看到的,有些已挂载设备仅限系统内部使用。可以注意到,默认大小均为 1024 字节,不利于直观查看,可附加==-h 参数进行更直观的查看。它会把输出中的磁盘空间按照用户易读的形式显示,通常用 M 来替代兆字节,用 G 替代吉字节==。
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sdb2 18G 7.4G 9.2G 45% /
/dev/sda1 99M 19M 76M 20% /boot
tmpfs 117M 0 117M 0% /dev/shm
/dev/sdb1 125M 112M 14M 90% /media/disk
# du 查看目录空间
通过 df 命令很容易发现哪个磁盘的存储空间快没了。系统管理员面临的下一个问题是,发生这种情况时要怎么办。另一个有用的命令是 du 命令。du 命令可以显示某个特定目录(默认情况下是当前目录)的磁盘使用情况。这一方法可用来快速判断系统上某个目录下是不是有超大文件。默认情况下,du 命令会显示当前目录下所有的文件、目录和子目录的磁盘使用情况,它会以磁盘块为单位来表明每个文件或目录占用了多大存储空间。对标准大小的目录来说,这个输出会是一个比较长的列表。
每行输出左边的数值是每个文件或目录占用的磁盘块数。注意,这个列表是从目录层级的最底部开始,然后按文件、子目录、目录逐级向上。 这么用 du 命令(不加参数,用默认参数)作用并不大。我们更想知道每个文件和目录占用了多大的磁盘空间,但如果还得逐页查找的话就没什么意义了。下面是能让 du 命令用起来更方便的几个命令行参数。
- -s:同时查询多目录时,依次只显示每个输出参数(目录)的总大小。
- -c:同时查询多目录时,显示所有已列出文件总的大小。
- -h:按用户易读的格式输出大小,即用 K 替代千字节,用 M 替代兆字节,用 G 替代吉字节。
$ du -sh ./Documents/ ./Desktop/
3.4G ./Documents/
58G ./Desktop/
$ du -shc ./Documents/ ./Desktop/
3.4G ./Documents/
58G ./Desktop/
62G 总用量
# 文件数据相关
# sort 排序
处理大量数据时的一个常用命令是 sort 命令。顾名思义,sort 命令是对数据进行排序的。默认情况下,sort 命令按照会话指定的默认语言的排序规则对文本文件中的数据行排序。
对数字排序时,如果你本期望这些数字能按值排序,就要失望了。默认情况下,sort 命令会把数字当做字符来执行标准的字符排序,产生的输出可能根本就不是你要的。解决这个问题可用-n 参数,它会告诉 sort 命令把数字识别成数字而不是字符,并且按值排序。
另一个常用的参数是-M,按月排序。Linux 的日志文件经常会在每行的起始位置有一个时间戳,用来表明事件是什么时候发生的,下面是一个例子。
Sep 13 07:10:09 testbox smartd[2718]: Device: /dev/sda, opened
如果将含有时间戳日期的文件按默认的排序方法来排序,并不会得到想要的结果。如果用-M 参数,sort 命令就能识别三字符的月份名,并相应地排序。
-k 和-t 参数在对按字段分隔的数据进行排序时非常有用,例如/etc/passwd 文件。可以用-t 参数来指定字段分隔符,然后用-k 参数来指定排序的字段。举个例子,对密码文件/etc/passwd 根据用户 ID 进行数值排序,可以这么做:
$ sort -t ':' -k 3 -n /etc/passwd
root:x:0:0::/root:/bin/bash
bin:x:1:1::/:/usr/bin/nologin
daemon:x:2:2::/:/usr/bin/nologin
mail:x:8:12::/var/spool/mail:/usr/bin/nologin
ftp:x:14:11::/srv/ftp:/usr/bin/nologin
http:x:33:33::/srv/http:/usr/bin/nologin
uuidd:x:68:68::/:/usr/bin/nologin
现在数据已经按第三个字段——用户 ID 的数值排序。
最后给出一个综合的例子:
$ du -s * | sort -nr
4649672 Android
2726928 Desktop
2224812 Documents
1139980 Games
47172 Downloads
29072 Pictures
560 ThunderNetwork
8 Music
4 下载
4 Videos
注意,-r 参数将结果按降序输出,这样就更容易看到目录下的哪些文件占用空间最多。本例中用到的管道命令(|)将 du 命令的输出重定向到 sort 命令。我们将在本书后面进一步讨论。
# grep 搜索
你会经常需要在大文件中找一行数据,而这行数据又埋藏在文件的中间。这时并不需要手动翻看整个文件,用 grep 命令来帮助查找就行了。grep 命令的命令行格式如下:
grep [options] pattern [file]
==grep 命令会在输入或指定的文件中查找包含匹配指定模式的字符的行==。grep 的输出就是包含了匹配模式的行。
$ grep three file1
three
$ grep t file1
two
three
第一个例子在文件 file1 中搜索能匹配模式 three 的文本。grep 命令输出了匹配了该模式的行。第二个例子在文件 file1 中搜索能匹配模式 t 的文本。这个例子里,file1 中有两行匹配了指定的模式,两行都输出了。由于 grep 命令非常流行,它经历了大量的更新。有很多功能被加进了 grep 命令。如果查看一下它的手册页面,你会发现它是多么的无所不能。
如果要进行反向搜索(输出不匹配该模式的行),可加-v 参数。
$ grep -v t file1
one
four
five
如果要显示匹配模式的行所在的行号,可加-n 参数
$ grep -n t file1
2:two
3:three
如果只要知道有多少行含有匹配的模式,可用-c 参数。
$ grep -c t file1
2
如果要指定多个匹配模式,可用-e 参数来指定每个模式。这个例子输出了含有字符 t 或字符 f 的所有行。
$ grep -e t -e f file1
two
three
four
five
默认情况下,grep 命令用基本的 Unix 风格正则表达式来匹配模式。Unix 风格正则表达式采用特殊字符来定义怎样查找匹配的模式。 以下是在 grep 搜索中使用正则表达式的简单例子。
$ grep [tf] file1
two
three
four
five
正则表达式中的方括号表明 grep 应该搜索包含 t 或者 f 字符的匹配。如果不用正则表达式,grep 就会搜索匹配字符串 tf 的文本。
egrep 命令是 grep 的一个衍生,支持 POSIX 扩展正则表达式。POSIX 扩展正则表达式含有更多的可以用来指定匹配模式的字符(后文会讲)。fgrep 则是另外一个版本,支持将匹配模式指定为用换行符分隔的一列固定长度的字符串。这样就可以把这列字符串放到一个文件中,然后在 fgrep 命令中用其在一个大型文件中搜索字符串了。egrep 与 grep -E 相同。 fgrep 与 grep -F 相同,所以掌握好 grep 就好。
# tar 压缩与归档
gzip 是非常流行的压缩工具软件包,使用方式也很简单,这个软件包含有下面的工具。
- gzip:用来压缩文件。
- gzcat:用来查看压缩过的文本文件的内容。
- gunzip:用来解压文件
$ gzip myprog #压缩文件
ls -l my*
-rwxrwxr-x 1 rich rich 2197 2007-09-13 11:29 myprog.gz
gzip 命令会压缩你在命令行指定的文件。也可以在命令行指定多个文件名甚至用通配符来一次性批量压缩文件。
$ gzip my*
虽然 gzip 命令能够很好地将数据压缩和归档进单个文件,但它不是 Unix 和 Linux 中的标准归档工具。目前,Unix 和 Linux 上最广泛使用的归档工具是 tar 命令。
tar 命令最开始是用来将文件写到磁带设备上归档的,然而它也能把输出写到文件里,这种用法在 Linux 上已经普遍用来归档数据了。关于 tar 的用法由于历史原因也有三种使用方式,较为复杂,记住常用方式即可。此时使用tldr tar
命令,即可很方便的查看常用用法。
# 网络相关
# lsof 查看java端口
lsof(list open files)是一个列出当前系统打开文件的工具。
lsof 查看端口占用语法格式:
lsof -i:端口号
# netstat 查看开放的tcp端口
netstat -tunlp 用于显示 tcp,udp 的端口和进程等相关情况。
netstat 查看端口占用语法格式:
netstat -tunlp | grep 端口号
- -t (tcp) 仅显示tcp相关选项
- -u (udp)仅显示udp相关选项
- -n 拒绝显示别名,能显示数字的全部转化为数字
- -l 仅列出在Listen(监听)的服务状态
- -p 显示建立相关链接的程序名