掌握liunx命令(二)
4.tree命令
tree命令用于以树状图的形式列出目录内容及结构,输入该命令后按回车键执行即可。
虽然ls命令可以很便捷地查看目录内有哪些文件,但无法直观地获取到目录内文件的层次结构。比如,假如目录A中有个B,B中又有个C,那么ls命令就只能看到最外面的A目录,显然有些时候这不太够用。tree命令则能够以树状图的形式列出目录内所有文件的结构。
我们来对比一下两者的区别。
使用ls命令查看目录内的文件:
[root@linuxprobe ~]# ls A Desktop Downloads Music Public Videos anaconda-ks.cfg Documents initial-setup-ks.cfg Pictures Templates
使用tree命令查看目录内文件名称以及结构:
[root@linuxprobe ~]# tree . ├── A │ └── B │ └── C ├── anaconda-ks.cfg ├── Desktop ├── Documents ├── Downloads ├── initial-setup-ks.cfg ├── Music ├── Pictures ├── Public ├── Templates └── Videos
5.find命令
find命令用于按照指定条件来查找文件所对应的位置,语法格式为“find [查找范围] 寻找条件”。
本书中会多次提到“Linux系统中的一切都是文件”,接下来就要见证这句话的分量了。在Linux系统中,搜索工作一般都是通过find命令来完成的,它可以使用不同的文件特性作为寻找条件(如文件名、大小、修改时间、权限等信息),一旦匹配成功则默认将信息显示到屏幕上。find命令的参数以及作用如表2-13所示。
表2-13 find命令中的参数以及作用
参数 | 作用 |
-name | 匹配名称 |
-perm | 匹配权限(mode为完全匹配,-mode为包含即可) |
-user | 匹配所有者 |
-group | 匹配所有组 |
-mtime -n +n | 匹配修改内容的时间(-n指n天以内,+n指n天以前) |
-atime -n +n | 匹配访问文件的时间(-n指n天以内,+n指n天以前) |
-ctime -n +n | 匹配修改文件权限的时间(-n指n天以内,+n指n天以前) |
-nouser | 匹配无所有者的文件 |
-nogroup | 匹配无所有组的文件 |
-newer f1 !f2 | 匹配比文件f1新但比f2旧的文件 |
-type b/d/c/p/l/f | 匹配文件类型(后面的字幕字母依次表示块设备、目录、字符设备、管道、链接文件、文本文件) |
-size | 匹配文件的大小(+50KB为查找超过50KB的文件,而-50KB为查找小于50KB的文件) |
-prune | 忽略某个目录 |
-exec …… {}\; | 后面可跟用于进一步处理搜索结果的命令(下文会有演示) |
这里需要重点讲解-exec参数的重要作用。这个参数用于把find命令搜索到的结果交由紧随其后的命令作进一步处理。它十分类似于第3章将要讲解的管道符技术,并且由于find命令对参数有特殊要求,因此虽然exec是长格式形式,但它的前面依然只需要一个减号(-)。
根据文件系统层次标准(Filesystem Hierarchy Standard)协议,Linux系统中的配置文件会保存到/etc目录中(详见第6章)。如果要想获取该目录中所有以host开头的文件列表,可以执行如下命令:
[root@linuxprobe ~]# find /etc -name "host*" -print /etc/host.conf /etc/hosts /etc/hosts.allow /etc/hosts.deny /etc/avahi/hosts /etc/hostname
如果要在整个系统中搜索权限中包括SUID权限的所有文件(详见第5章),只需使用-4000即可:
[root@linuxprobe ~]# find / -perm -4000 -print /usr/bin/fusermount /usr/bin/chage /usr/bin/gpasswd /usr/bin/newgrp /usr/bin/umount /usr/bin/mount /usr/bin/su /usr/bin/pkexec /usr/bin/crontab /usr/bin/passwd ………………省略部分输出信息………………
进阶实验:
在整个文件系统中找出所有归属于linuxprobe用户的文件并复制到/root/findresults目录中。
该实验的重点是“-exec {} \;”参数,其中的{}表示find命令搜索出的每一个文件,并且命令的结尾必须是“\;”。完成该实验的具体命令如下:[root@linuxprobe ~]# find / -user linuxprobe -exec cp -a {} /root/findresults/ \;
6.locate命令
locate命令用于按照名称快速搜索文件所对应的位置,语法格式为“locate文件名称”。
使用find命令进行全盘搜索虽然更准确,但是效率有点低。如果仅仅是想找一些常见的且又知道大概名称的文件,不如试试locate命令。在使用locate命令时,先使用updatedb命令生成一个索引库文件,这个库文件的名字是/var/lib/mlocate/mlocate.db,后续在使用locate命令搜索文件时就是在该库中进行查找操作,速度会快很多。
第一次使用locate命令之前,记得先执行updatedb命令来生成索引数据库,然后再进行查找:
[root@linuxprobe ~]# updatedb [root@linuxprobe ~]# ls -l /var/lib/mlocate/mlocate.db -rw-r-----. 1 root slocate 2945917 Sep 13 17:54 /var/lib/mlocate/mlocate.db
使用locate命令搜索出所有包含“whereis”名称的文件所在的位置:
[root@linuxprobe ~]# locate whereis /usr/bin/whereis /usr/share/bash-completion/completions/whereis /usr/share/man/man1/whereis.1.gz
7.whereis命令
whereis命令用于按照名称快速搜索二进制程序(命令)、源代码以及帮助文件所对应的位置,语法格式为“whereis命令名称”。
简单来说,whereis命令也是基于updatedb命令所生成的索引库文件进行搜索,它与locate命令的区别是不关心那些相同名称的文件,仅仅是快速找到对应的命令文件及其帮助文件所在的位置。
下面使用whereis命令分别查找出ls和pwd命令所在的位置:
[root@linuxprobe ~]# whereis ls ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz [root@linuxprobe ~]# whereis pwd pwd: /usr/bin/pwd /usr/share/man/man1/pwd.1.gz /usr/share/man/man1p/pwd.1p.gz
8.which命令
which命令用于按照指定名称快速搜索二进制程序(命令)所对应的位置,语法格式为“which命令名称”。
which命令是在PATH变量所指定的路径中,按照指定条件搜索命令所在的路径。也就是说,如果我们既不关心同名文件(find与locate),也不关心命令所对应的源代码和帮助文件(whereis),仅仅是想找到命令本身所在的路径,那么这个which命令就太合适了。下面查找一下locate和whereis命令所对应的路径:
[root@linuxprobe ~]# which locate /usr/bin/locate [root@linuxprobe ~]# which whereis /usr/bin/whereis
2.6 文本文件编辑命令
通过前面几个小节的学习,读者应该已经掌握了切换工作目录及对文件的管理方法。在Linux系统中,一切都是文件,对服务程序进行配置自然也就是编辑程序的配置文件。如果不能熟练地查阅系统或服务的配置文件,那以后工作时可就真的要尴尬了。本节将讲解几条用于查看文本文件内容的命令。至于相对比较复杂的文本编辑器工具,将在第4章与Shell脚本一起讲解。
1.cat命令
cat命令用于查看纯文本文件(内容较少的),英文全称为“concatenate”,语法格式为“cat [参数] 文件名称”。
Linux系统中有多个用于查看文本内容的命令,每个命令都有自己的特点,比如这个cat命令就是用于查看内容较少的纯文本文件。cat这个命令也很好记,因为cat在英语中是“猫”的意思,小猫咪是不是给您一种娇小、可爱的感觉呢?
如果在查看文本内容时还想顺便显示行号的话,不妨在cat命令后面追加一个-n参数:
[root@linuxprobe ~]# cat -n initial-setup-ks.cfg 1 #version=RHEL8 2 # X Window System configuration information 3 xconfig --startxonboot 4 # License agreement 5 eula --agreed 6 # Use graphical install 7 graphical 8 # Network information 9 network --bootproto=dhcp --device=ens160 --onboot=off --ipv6=auto --no-activate 10 network --bootproto=dhcp --hostname=localhost.localdomain 11 repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream 12 ignoredisk --only-use=sda 13 # Use CDROM installation media 14 cdrom 15 # Run the Setup Agent on first boot 16 firstboot --enable 17 # System services ………………省略部分输出信息………………
2.more命令
more命令用于查看纯文本文件(内容较多的),语法格式为“more [参数] 文件名称”。
如果需要阅读长篇小说或者非常长的配置文件,那么“小猫咪”可就真的不适合了。因为一旦使用cat命令阅读长篇的文本内容,信息就会在屏幕上快速翻滚,导致自己还没有来得及看到,内容就已经翻篇了。因此对于长篇的文本内容,推荐使用more命令来查看。more命令会在最下面使用百分比的形式来提示您已经阅读了多少内容;还可以使用空格键或回车键向下翻页:
[root@linuxprobe ~]# more initial-setup-ks.cfg #version=RHEL8 # X Window System configuration information xconfig --startxonboot # License agreement eula --agreed # Use graphical install graphical # Network information network --bootproto=dhcp --device=ens160 --onboot=off --ipv6=auto --no-activate network --bootproto=dhcp --hostname=localhost.localdomain repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream ignoredisk --only-use=sda # Use CDROM installation media cdrom # Run the Setup Agent on first boot firstboot --enable # System services services --disabled="chronyd" # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 --More--(41%)
3.head命令
head命令用于查看纯文本文件的前N行,语法格式为“head [参数] 文件名称”。
在阅读文本内容时,谁也难以保证会按照从头到尾的顺序往下看完整个文件。如果只想查看文本中前10行的内容,该怎么办呢?head命令就能派上用场了:
[root@linuxprobe ~]# head -n 10 initial-setup-ks.cfg #version=RHEL8 # X Window System configuration information xconfig --startxonboot # License agreement eula --agreed # Use graphical install graphical # Network information network --bootproto=dhcp --device=ens160 --onboot=off --ipv6=auto --no-activate network --bootproto=dhcp --hostname=localhost.localdomain
4.tail命令
tail命令用于查看纯文本文件的后N行或持续刷新文件的最新内容,语法格式为“tail [参数] 文件名称”。
我们可能还会遇到另外一种情况,比如需要查看文本内容的最后10行,这时就需要用到tail命令了。tail命令的操作方法与head命令非常相似,只需要执行“tail -n 20文件名称”命令就可以达到这样的效果:
[root@linuxprobe ~]# tail -n 10 initial-setup-ks.cfg %addon com_redhat_subscription_manager %end %addon ADDON_placeholder --disable --reserve-mb=auto %end %anaconda pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty %end
tail命令最强悍的功能是能够持续刷新一个文件的内容,当想要实时查看最新的日志文件时,这特别有用,此时的命令格式为“tail -f文件名称”:
[root@linuxprobe ~]# tail -f /var/log/messages Sep 15 00:14:01 localhost rsyslogd[1392]: imjournal: sd_journal_get_cursor() failed: Cannot assign requested address [v8.37.0-9.el8] Sep 15 00:14:01 localhost rsyslogd[1392]: imjournal: journal reloaded... [v8.37.0-9.el8 try http://www.rsyslog.com/e/0 ] Sep 15 00:14:01 localhost systemd[1]: Started update of the root trust anchor for DNSSEC validation in unbound. Sep 15 00:14:01 localhost sssd[kcm][2764]: Shutting down Sep 15 00:14:06 localhost systemd[1]: Starting SSSD Kerberos Cache Manager... Sep 15 00:14:06 localhost systemd[1]: Started SSSD Kerberos Cache Manager. Sep 15 00:14:06 localhost sssd[kcm][3989]: Starting up Sep 15 00:14:26 localhost NetworkManager[1203]: <info> [1600100066.4675] audit: op="sleep-control" arg="off" pid=3990 uid=0 result="fail" reason="Already awake" Sep 15 00:19:04 localhost org.gnome.Shell.desktop[2600]: Window manager warning: last_user_time (2361102) is greater than comparison timestamp (2361091). This most likely represents a buggy client sending inaccurate timestamps in messages such as _NET_ACTIVE_WINDOW. Trying to work around... Sep 15 00:19:04 localhost org.gnome.Shell.desktop[2600]: Window manager warning: W14 (root@local) appears to be one of the offending windows with a timestamp of 2361102. Working around...
5.tr命令
tr命令用于替换文本内容中的字符,英文全称为“translate”,语法格式为“tr [原始字符] [目标字符]”。
在很多时候,我们想要快速地替换文本中的一些词汇,又或者想把整个文本内容都进行替换。如果进行手工替换,难免工作量太大,尤其是需要处理大批量的内容时,进行手工替换更是不现实。这时,就可以先使用cat命令读取待处理的文本,然后通过管道符(详见第3章)把这些文本内容传递给tr命令进行替换操作即可。例如,把某个文本内容中的英文全部替换为大写:
[root@linuxprobe ~]# cat anaconda-ks.cfg | tr [a-z] [A-Z] #VERSION=RHEL8 IGNOREDISK --ONLY-USE=SDA AUTOPART --TYPE=LVM # PARTITION CLEARING INFORMATION CLEARPART --ALL --INITLABEL --DRIVES=SDA # USE GRAPHICAL INSTALL GRAPHICAL REPO --NAME="APPSTREAM" --BASEURL=FILE:///RUN/INSTALL/REPO/APPSTREAM # USE CDROM INSTALLATION MEDIA CDROM # KEYBOARD LAYOUTS KEYBOARD --VCKEYMAP=US --XLAYOUTS='US' # SYSTEM LANGUAGE LANG EN_US.UTF-8 # NETWORK INFORMATION NETWORK --BOOTPROTO=DHCP --DEVICE=ENS160 --ONBOOT=OFF --IPV6=AUTO --NO-ACTIVATE NETWORK --HOSTNAME=LOCALHOST.LOCALDOMAIN # ROOT PASSWORD ROOTPW --ISCRYPTED $6$TTBUW5DKOPYQQ.VI$RMK9FCGHOJOQ2QAPRURTQM.QOK2NN3YFN/I4F/FALVGGGND9XOIYFBRXDN16WWIZIASJ0/CR06U66IPEOGLPJ. # X WINDOW SYSTEM CONFIGURATION INFORMATION XCONFIG --STARTXONBOOT # RUN THE SETUP AGENT ON FIRST BOOT FIRSTBOOT --ENABLE # SYSTEM SERVICES SERVICES --DISABLED="CHRONYD" # SYSTEM TIMEZONE TIMEZONE ASIA/SHANGHAI --ISUTC --NONTP ………………省略部分输出信息………………
6.wc命令
wc命令用于统计指定文本文件的行数、字数或字节数,英文全称为“word counts”,语法格式为“wc [参数] 文件名称”。
每次我在课堂上讲到这个命令时,总有同学会联想到一种公共设施,其实这两者毫无关联。wc命令用于统计文本的行数、字数、字节数等。如果为了方便自己记住这个命令的作用,也可以联想到上厕所时好无聊,无聊到数完了手中的如厕读物上有多少行字。
wc的参数以及相应的作用如表2-14所示。
表2-14 wc命令中的参数以及作用
参数 | 作用 |
-l | 只显示行数 |
-w | 只显示单词数 |
-c | 只显示字节数 |
在Linux系统中,/etc/passwd是用于保存所有用户信息的文件,要统计当前系统中有多少个用户,可以使用下面的命令来进行查询,是不是很神奇:
[root@linuxprobe ~]# wc -l /etc/passwd 45 /etc/passwd
7.stat命令
stat命令用于查看文件的具体存储细节和时间等信息,英文全称为“status”,语法格式为“stat文件名称”。
大家都知道,文件有一个修改时间。其实,除了修改时间之外,Linux系统中的文件包含3种时间状态,分别是Access Time(内容最后一次被访问的时间,简称为Atime),Modify Time(内容最后一次被修改的时间,简称为Mtime)以及Change Time(文件属性最后一次被修改的时间,简称为Ctime)。
下面使用state命令查看文件的这3种时间状态信息:
[root@linuxprobe ~]# stat anaconda-ks.cfg File: anaconda-ks.cfg Size: 1407 Blocks: 8 IO Block: 4096 regular file Device: fd00h/64768d Inode: 35321091 Links: 1 Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root) Context: system_u:object_r:admin_home_t:s0 Access: 2020-07-21 05:16:52.347279499 +0800 Modify: 2020-07-21 05:09:16.421009316 +0800 Change: 2020-07-21 05:09:16.421009316 +0800 Birth: -
8.grep命令
grep命令用于按行提取文本内容,语法格式为“grep [参数] 文件名称”。
grep命令是用途最广泛的文本搜索匹配工具。它虽然有很多参数,但是大多数基本上都用不到。刘遄老师在总结了10多年的运维工作和培训教学的经验后,提出的本书的写作理念“去掉不实用的内容”绝对不是信口开河。如果一名IT培训讲师的水平只能停留在“技术的搬运工”层面,而不能对优质技术知识进行提炼总结,对他的学生来讲绝非好事。有鉴于此,我们在这里只讲grep命令两个最常用的参数:
-n参数用来显示搜索到的信息的行号;
-v参数用于反选信息(即没有包含关键词的所有信息行)。
这两个参数几乎能完成您日后80%的工作需要,至于其他上百个参数,即使以后在工作期间遇到了,再使用man grep命令查询也来得及。
grep命令的参数及其作用如表2-15所示。
表2-15 grep命令中的参数及其作用
参数 | 作用 |
-b | 将可执行文件(binary)当作文本文件(text)来搜索 |
-c | 仅显示找到的行数 |
-i | 忽略大小写 |
-n | 显示行号 |
-v | 反向选择——仅列出没有“关键词”的行。 |
在Linux系统中,/etc/passwd文件保存着所有的用户信息,而一旦用户的登录终端被设置成/sbin/nologin,则不再允许登录系统,因此可以使用grep命令查找出当前系统中不允许登录系统的所有用户的信息:
[root@linuxprobe ~]# grep /sbin/nologin /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ………………省略部分输出过程信息………………
9.cut命令
cut命令用于按“列”提取文本内容,语法格式为“cut [参数] 文件名称”。
系统文件在保存用户数据信息时,每一项值之间是采用冒号来间隔的,先查看一下:
[root@linuxprobe ~]# head -n 2 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin
一般而言,按基于“行”的方式来提取数据是比较简单的,只需要设置好要搜索的关键词即可。但是如果按“列”搜索,不仅要使用-f参数设置需要查看的列数,还需要使用-d参数来设置间隔符号。
接下来使用下述命令尝试提取出passwd文件中的用户名信息,即提取以冒号(:)为间隔符号的第一列内容:
[root@linuxprobe ~]# cut -d : -f 1 /etc/passwd root bin daemon adm lp sync shutdown halt mail operator games ftp nobody dbus ………………省略部分输出信息………………
10.diff命令
diff命令用于比较多个文件之间内容的差异,英文全称为“different”,语法格式为“diff [参数] 文件名称A 文件名称B”。
在使用diff命令时,不仅可以使用--brief参数来确认两个文件是否相同,还可以使用-c参数来详细比较出多个文件的差异之处。这绝对是判断文件是否被篡改的有力神器。例如,先使用cat命令分别查看diff_A.txt和diff_B.txt文件的内容,然后进行比较:
[root@linuxprobe ~]# cat diff_A.txt Welcome to linuxprobe.com Red Hat certified Free Linux Lessons Professional guidance Linux Course [root@linuxprobe ~]# cat diff_B.txt Welcome tooo linuxprobe.com Red Hat certified Free Linux LeSSonS ..... Professional guidance Linux Course
接下来使用diff --brief命令显示比较后的结果,判断文件是否相同:
[root@linuxprobe ~]# diff --brief diff_A.txt diff_B.txt Files diff_A.txt and diff_B.txt differ
最后使用带有-c参数的diff命令来描述文件内容具体的不同:
[root@linuxprobe ~]# diff -c diff_A.txt diff_B.txt *** diff_A.txt 2020-08-30 18:07:45.230864626 +0800 --- diff_B.txt 2020-08-30 18:08:52.203860389 +0800 *************** *** 1,5 **** ! Welcome to linuxprobe.com Red Hat certified ! Free Linux Lessons Professional guidance Linux Course --- 1,7 ---- ! Welcome tooo linuxprobe.com ! Red Hat certified ! Free Linux LeSSonS ! ..... Professional guidance Linux Course
11.uniq命令
uniq命令用于去除文本中连续的重复行,英文全称为“unique”,语法格式为“uniq [参数] 文件名称”。
由uniq命令的英文全称unique(独特的,唯一的)可知,该命令的作用是用来去除文本文件中连续的重复行,中间不能夹杂其他文本行(非相邻的默认不会去重)—去除了重复的,保留的都是唯一的,自然也就是“独特的”“唯一的”了。
我们使用uniq命令对两个文本内容进行操作,区别一目了然:
[root@linuxprobe ~]# cat uniq.txt Welcome to linuxprobe.com Welcome to linuxprobe.com Welcome to linuxprobe.com Welcome to linuxprobe.com Red Hat certified Free Linux Lessons Professional guidance Linux Course [root@linuxprobe ~]# uniq uniq.txt Welcome to linuxprobe.com Red Hat certified Free Linux Lessons Professional guidance Linux Course
12.sort命令
sort命令用于对文本内容进行再排序,语法格式为“sort [参数] 文件名称”。
有时文本中的内容顺序不正确,一行行地手动修改实在太麻烦了。此时使用sort命令就再合适不过了,它能够对文本内容进行再次排序。这个命令千万不能只讲理论,一定要借助于实战让大家一看就懂。sort命令的参数及其作用如表2-16所示。
表2-16 sort命令中的参数及其作用
参数 | 作用 |
-f | 忽略大小写 |
-b | 忽略缩进与空格 |
-n | 以数值型排序 |
-r | 反向排序 |
-u | 去除重复行 |
-t | 指定间隔符 |
-k | 设置字段范围 |
首先,在执行sort命令后默认会按照字母顺序进行排序,非常方便:
[root@linuxprobe ~]# cat fruit.txt banana pear apple orange raspaberry [root@linuxprobe ~]# sort fruit.txt apple banana orange pear raspaberry
此外,与uniq命令不同,sort命令是无论内容行之间是否夹杂有其他内容,只要有两个一模一样的内容行,立马就可以使用-u参数进行去重操作:
[root@linuxprobe ~]# cat sort.txt Welcome to linuxprobe.com Red Hat certified Welcome to linuxprobe.com Free Linux Lessons Linux Course [root@linuxprobe ~]# sort -u sort.txt Free Linux Lessons Linux Course Red Hat certified Welcome to linuxprobe.com
想对数字进行排序?一点问题都没有,而且完全不用担心出现1大于20这种问题(因为有些命令只比较数字的第一位,忽略了十、百、千的位):
[root@linuxprobe ~]# cat number.txt 45 12 3 98 82 67 24 56 9 [root@linuxprobe ~]# sort -n number.txt 3 9 12 24 45 56 67 82 98
最后,我们挑战一个“高难度”的小实验。下面的内容节选自/etc/passwd文件中的前5个字段,并且进行了混乱排序。
[root@linuxprobe ~]# cat user.txt tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon polkitd:x:998:996:User for polkitd geoclue:x:997:995:User for geoclue rtkit:x:172:172:RealtimeKit pulse:x:171:171:PulseAudio System Daemon qemu:x:107:107:qemu user usbmuxd:x:113:113:usbmuxd user unbound:x:996:991:Unbound DNS resolver rpc:x:32:32:Rpcbind Daemon gluster:x:995:990:GlusterFS daemons
不难看出,上面其实是5个字段,各个字段之间是用了冒号进行间隔,如果想以第3个字段中的数字作为排序依据,那么可以用-t参数指定间隔符,用-k参数指定第几列,用-n参数进行数字排序来搞定:
[root@linuxprobe ~]# sort -t : -k 3 -n user.txt rpc:x:32:32:Rpcbind Daemon tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon qemu:x:107:107:qemu user usbmuxd:x:113:113:usbmuxd user pulse:x:171:171:PulseAudio System Daemon rtkit:x:172:172:RealtimeKit gluster:x:995:990:GlusterFS daemons unbound:x:996:991:Unbound DNS resolver geoclue:x:997:995:User for geoclue polkitd:x:998:996:User for polkitd
2.7 文件目录管理命令
目前为止,我们学习Linux命令的过程就像是在夯实地基,虽然表面上“高楼未起”,但其实大家的内功已经相当深厚了。有了上面的知识铺垫,我们将在本节介绍Linux系统日常运维工作中最常用的命令,实现对文件的创建、修改、复制、剪切、更名与删除等操作。
1.touch命令
touch命令用于创建空白文件或设置文件的时间,语法格式为“touch [参数] 文件名称”。
在创建空白的文本文件方面,这个touch命令相当简洁,简捷到没有必要铺开去讲。比如,touch linuxprobe命令可以创建出一个名为linuxprobe的空白文本文件。对touch命令来讲,有难度的操作主要是体现在设置文件内容的修改时间(Mtime)、文件权限或属性的更改时间(Ctime)与文件的访问时间(Atime)上面。touch命令的参数及其作用如表2-17所示。
表2-17 touch命令中的参数及其作用
参数 | 作用 |
-a | 仅修改“读取时间”(atime) |
-m | 仅修改“修改时间”(mtime) |
-d | 同时修改atime与mtime |
接下来,先使用ls命令查看一个文件的修改时间,随后修改这个文件,最后再查看一下文件的修改时间,看是否发生了变化:
[root@linuxprobe ~]# ls -l anaconda-ks.cfg -rw-------. 1 root root 1213 May 4 15:44 anaconda-ks.cfg [root@linuxprobe ~]# echo "Visit the LinuxProbe.com to learn linux skills" >> anaconda-ks.cfg [root@linuxprobe ~]# ls -l anaconda-ks.cfg -rw-------. 1 root root 1260 Aug 2 01:26 anaconda-ks.cfg
如果不想让别人知道我们修改了它,那么这时就可以用touch命令把修改后的文件时间设置成修改之前的时间(很多黑客就是这样做的呢):
[root@linuxprobe ~]# touch -d "2020-05-04 15:44" anaconda-ks.cfg [root@linuxprobe ~]# ls -l anaconda-ks.cfg -rw-------. 1 root root 1260 May 4 15:44 anaconda-ks.cfg
2.mkdir命令
mkdir命令用于创建空白的目录,英文全称为“make directory”,语法格式为“mkdir [参数] 目录名称”。
除了能创建单个空白目录外,mkdir命令还可以结合-p参数来递归创建出具有嵌套层叠关系的文件目录:
[root@linuxprobe ~]# mkdir linuxprobe [root@linuxprobe ~]# cd linuxprobe [root@linuxprobe linuxprobe]# mkdir -p a/b/c/d/e [root@linuxprobe linuxprobe]# cd a [root@linuxprobe a]# cd b [root@linuxprobe b]#
3.cp命令
cp命令用于复制文件或目录,英文全称为“copy”,语法格式为“cp [参数] 源文件名称 目标文件名称”。
大家对文件复制操作应该不陌生,几乎每天都会使用到。在Linux系统中,复制操作具体分为3种情况:
如果目标文件是目录,则会把源文件复制到该目录中;
如果目标文件也是普通文件,则会询问是否要覆盖它;
如果目标文件不存在,则执行正常的复制操作。
复制命令基本不会出错,唯一需要记住的就是在复制目录时要加上-r参数。cp命令的参数及其作用如表2-18所示。
表2-18 cp命令中的参数及其作用
参数 | 作用 |
-p | 保留原始文件的属性 |
-d | 若对象为“链接文件”,则保留该“链接文件”的属性 |
-r | 递归持续复制(用于目录) |
-i | 若目标文件存在则询问是否覆盖 |
-a | 相当于-pdr(p、d、r为上述参数) |
接下来,使用touch命令创建一个名为install.log的普通空白文件,然后将其复制为一份名为x.log的备份文件,最后再使用ls命令查看目录中的文件:
[root@linuxprobe ~]# touch install.log [root@linuxprobe ~]# cp install.log x.log [root@linuxprobe ~]# ls install.log x.log
4.mv命令
mv命令用于剪切或重命名文件,英文全称为“move”,语法格式为“mv [参数] 源文件名称 目标文件名称”。
剪切操作不同于复制操作,因为它默认会把源文件删除,只保留剪切后的文件。如果在同一个目录中将某个文件剪切后还粘贴到当前目录下,其实也就是对该文件进行了重命名操作:
[root@linuxprobe ~]# mv x.log linux.log [root@linuxprobe ~]# ls install.log linux.log
5.rm命令
rm命令用于删除文件或目录,英文全称为“remove”,语法格式为“rm [参数] 文件 名称”。
在Linux系统中删除文件时,系统会默认向您询问是否要执行删除操作,如果不想总是看到这种反复的确认信息,可在rm命令后跟上-f参数来强制删除。另外,要想删除一个目录,需要在rm命令后面加一个-r参数才可以,否则删除不掉。rm命令的参数及其作用如表2-19所示。
表2-19 rm命令中的参数及其作用
参数 | 作用 |
-f | 强制执行 |
-i | 删除前询问 |
-r | 删除目录 |
-v | 显示过程 |
下面尝试删除前面创建的install.log和linux.log文件,大家感受一下加与不加-f参数的区别:
[root@linuxprobe ~]# rm install.log rm: remove regular empty file ‘install.log’? y [root@linuxprobe ~]# rm -f linux.log [root@linuxprobe ~]# ls [root@linuxprobe ~]#
6.dd命令
dd命令用于按照指定大小和个数的数据块来复制文件或转换文件,语法格式为“dd if=参数值of=参数值count=参数值bs=参数值”。
dd命令是一个比较重要而且比较有特色的命令,它能够让用户按照指定大小和个数的数据块来复制文件的内容。当然,如果愿意的话,还可以在复制过程中转换其中的数据。Linux系统中有一个名为/dev/zero的设备文件,每次在课堂上解释它时都充满哲学理论的色彩。因为这个文件不会占用系统存储空间,但却可以提供无穷无尽的数据,因此常常使用它作为dd命令的输入文件,来生成一个指定大小的文件。dd命令的参数及其作用如表2-20所示。
表2-20 dd命令中的参数及其作用
参数 | 作用 |
if | 输入的文件名称 |
of | 输出的文件名称 |
bs | 设置每个“块”的大小 |
count | 设置要复制“块”的个数 |
例如,用dd命令从/dev/zero设备文件中取出一个大小为560MB的数据块,然后保存成名为560_file的文件。在理解了这个命令后,以后就能随意创建任意大小的文件了:
[root@linuxprobe ~]# dd if=/dev/zero of=560_file count=1 bs=560M 1+0 records in 1+0 records out 587202560 bytes (587 MB, 560 MiB) copied, 1.28667 s, 456 MB/s
dd命令的功能也绝不仅限于复制文件这么简单。如果想把光驱设备中的光盘制作成iso格式的镜像文件,在Windows系统中需要借助于第三方软件才能做到,但在Linux系统中可以直接使用dd命令来压制出光盘镜像文件,将它变成一个可立即使用的iso镜像:
[root@linuxprobe ~]# dd if=/dev/cdrom of=RHEL-server-8.0-x86_64-LinuxProbe.Com.iso 13873152+0 records in 13873152+0 records out 7103053824 bytes (7.1 GB, 6.6 GiB) copied, 27.8812 s, 255 MB/s
考虑到有些读者会纠结bs块大小与count块个数的关系,下面举一个吃货的例子进行解释。假设小明的饭量(即需求)是一个固定的值,用来盛饭的勺子的大小是bs块的大小,而用勺子盛饭的次数则是count块的个数。小明要想吃饱(满足需求),则需要在勺子大小(bs块大小)与用勺子盛饭的次数(count块个数)之间进行平衡。勺子越大,用勺子盛饭的次数就越少。由上可见,bs与count都是用来指定容量的大小,只要能满足需求,可随意组合搭配方式。
7.file命令
file命令用于查看文件的类型,语法格式为“file文件名称”。
在Linux系统中,由于文本、目录、设备等所有这些一切都统称为文件,但是它们又不像Windows系统那样都有后缀,因此很难通过文件名一眼判断出具体的文件类型,这时就需要使用file命令来查看文件类型了。
[root@linuxprobe ~]# file anaconda-ks.cfg anaconda-ks.cfg: ASCII text [root@linuxprobe ~]# file /dev/sda /dev/sda: block special
Tips
在Windows系统中打开文件时,一般是通过用户双击鼠标完成的,系统会自行判断用户双击的文件是什么类型,因此需要有后缀进行区别。而Linux系统则是根据用户执行的命令来调用文件,例如执行cat命令查看文本,执行bash命令执行脚本等,所以也就不需要强制让用户给文件设置后缀了。
8.tar命令
tar命令用于对文件进行打包压缩或解压,语法格式为“tar参数 文件名称”。
在网络上,人们越来越倾向于传输压缩格式的文件,原因是压缩文件的体积小,在网速相同的情况下,体积越小则传输时间越短。在Linux系统中,主要使用的是.tar、.tar.gz或.tar.bz2格式,大家不用担心格式太多而记不住,其实这些格式大部分都是由tar命令生成的。tar命令的参数及其作用如表2-21所示。
表2-21 tar命令中的参数及其作用
参数 | 作用 |
-c | 创建压缩文件 |
-x | 解开压缩文件 |
-t | 查看压缩包内有哪些文件 |
-z | 用Gzip压缩或解压 |
-j | 用bzip2压缩或解压 |
-v | 显示压缩或解压的过程 |
-f | 目标文件名 |
-p | 保留原始的权限与属性 |
-P | 使用绝对路径来压缩 |
-C | 指定解压到的目录 |
首先,-c参数用于创建压缩文件,-x参数用于解压文件,因此这两个参数不能同时使用。其次,-z参数指定使用gzip格式来压缩或解压文件,-j参数指定使用bzip2格式来压缩或解压文件。用户使用时则是根据文件的后缀来决定应使用何种格式的参数进行解压。在执行某些压缩或解压操作时,可能需要花费数个小时,如果屏幕一直没有输出,您一方面不好判断打包的进度情况,另一方面也会怀疑电脑死机了,因此非常推荐使用-v参数向用户不断显示压缩或解压的过程。-C参数用于指定要解压到哪个指定的目录。-f参数特别重要,它必须放到参数的最后一位,代表要压缩或解压的软件包名称。刘遄老师一般使用“tar -czvf压缩包名称.tar.gz要打包的目录”命令把指定的文件进行打包压缩;相应的解压命令为“tar -xzvf压缩包名称.tar.gz”。下面我们逐个演示打包压缩与解压的操作,先使用tar命令把/etc目录通过gzip格式进行打包压缩,并把文件命名为etc.tar.gz:
[root@linuxprobe ~]# tar czvf etc.tar.gz /etc tar: Removing leading `/' from member names /etc/ /etc/fstab /etc/crypttab /etc/mtab /etc/fonts/ /etc/fonts/conf.d/ /etc/fonts/conf.d/65-0-madan.conf /etc/fonts/conf.d/59-liberation-sans.conf /etc/fonts/conf.d/90-ttf-arphic-uming-embolden.conf /etc/fonts/conf.d/59-liberation-mono.conf /etc/fonts/conf.d/66-sil-nuosu.conf ………………省略部分压缩过程信息………………
接下来将打包后的压缩包文件指定解压到/root/etc目录中(先使用mkdir命令创建/root/etc目录):
[root@linuxprobe ~]# mkdir /root/etc [root@linuxprobe ~]# tar xzvf etc.tar.gz -C /root/etc etc/ etc/fstab etc/crypttab etc/mtab etc/fonts/ etc/fonts/conf.d/ etc/fonts/conf.d/65-0-madan.conf etc/fonts/conf.d/59-liberation-sans.conf etc/fonts/conf.d/90-ttf-arphic-uming-embolden.conf etc/fonts/conf.d/59-liberation-mono.conf etc/fonts/conf.d/66-sil-nuosu.conf etc/fonts/conf.d/65-1-vlgothic-gothic.conf etc/fonts/conf.d/65-0-lohit-bengali.conf etc/fonts/conf.d/20-unhint-small-dejavu-sans.conf ………………省略部分解压过程信息………………