linux中数组的索引从0开始,其他默认从1开始,例如没有第0列,从第1列开始
在Unix中一切(包括网络套接口)都是文件
在命令行中,无论几个空格,都当成一个空格看待
在linux中,在命令行中通过执行命令的方式来改变系统或软件配置时,效果只适用于当前的shell,即都是暂时的(重新登录或重启系统后效果会失效)。如果想要永久更改,需要将配置写入到相应的配置文件中。
可全局搜索关键字快速定位:
Knowledge:知识
tips/[tips]:实用点子
point[point]: 个人理解(非官方)
通配符代表bash操作接口的一个功能,但是正则表达式是一种字符串处理的表达方式。[tips]
通配符
* 代表【0个到无穷个】任意字符
? 代表【一定有一个】任意字符
[]【一定有一个在括号内】的字符(非任意字符)。例如【abcd】代表【一定有一个字符,可能是a、b、c、d这四个中的任何一个】。(和正则表达式中的含义相同)
[-] 代表【在编码顺序内的所有字符】,例如[0-9]代表一定有一个字符,这个字符是0和9之间的所有数字中的任何一个。(和正则表达式中的含义相同)
[^] 代表【反向选择】,例如[^abc]表示一定有一个字符,只要是非a、b、c的其他字符就接受的意思。(和正则表达式中的含义相同)
正则表达式
见《正则表达式.md.md》
正则表达式的特殊字符与一般在命令行输入命令的通配符并不相通,例如,在通配符中*表示【0到无穷多个字符】的意思,而正则表达式中,*表示*前面的字符【重复0到无穷多次】的意思。
例 不支持正则表达式的ls命令中,若我们使用ls -l *,代表列出任意文件名的文件,ls -l a*表示列出以a开头的任何文件名的文件。但在正则表达式中,我们要找到含有以a开头的文件,要使用ls | grep '^a.*' [tips]
ctrl u 删除光标前面的所有内容
ctrl k删除光标及光标后面的所有内容
ctrl a 光标移动到命令行的开头
ctrl e光标移动到命令行的结尾
. 当前目录
.. 上一层目录
- 上一次的工作路径
~ 当前用户的家目录
~account 代表account这个使用者的家目录(account是个账号名称)
#
\
|
;
$
&
!
/
>、>>
<、<<
''
""
``
()
{}
./可执行文件
绝对路径/可执行文件
bash 可执行文件
sh 可执行文件
cd ~dmtsai #进入dmtsai这个使用者的家目录,亦即/home/dmtsai
cd ~ #表示回到当前用户的家目录
cd #不加任何路径,也表示回到当前用户的家目录
建立新目录
mkdir [OPTION]... DIRECTORY... 可以新建多个目录
-m 设置目录的权限,直接设置,不适用默认权限(umask)
-p 递归建立目录,如果目录存在则不建立,不会报目录已经存在的错误
[root@centos79 ~]# mkdir -m 711 test1 #新建目录,且目录权限为711
[root@centos79 ~]# ll
total 8
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
drwx--x--x. 2 root root 6 Dec 3 04:25 test1
-rw-r--r--. 1 root root 0 Dec 3 04:01 testtouch
touch [OPTION]... FILE...
修改文件时间或创建文件
-a 仅自定义access time
-c 仅修改文件的时间,若该文件不存在则不建立新文件
-m 仅修改mtime
-d 后面可以接欲自定义的日期而不是用目前的日期,也可以使用--date=”日期或时间“,修改文件的atime和mtime
-t 后面可以接欲自定义的时间而不是用目前的时间,格式为[YYYYMMDDhhmm],修改文件的atime和mtime
touch testtouch
#在默认状态下,如果touch后面接已存在的文件名,则该文件的三个时间(atime、ctime、mtime)都会更新为目前的时间。
#若该文件不存在,则会建立一个新的空文件
复制文件时,即使复制文件的所有属性,也没办法复制ctime这个属性。[tips]
knowledge:atime、ctime、mtime
修改时间【modification time, mtime】
当该文件的【内容数据】变更时,就会更新这个时间,内容数据指的是文件的内容,而不是文件的属性或权限
状态时间【status time, ctime】
当该文件的【状态】改变时,就会更新这个时间,举例来说,像是权限与属性被更改了,都会更新这个时间
读取时【access time, atime】
当【该文件的内容被读取】时,就会更新这个读取时间,举例来说,我们使用cat去读取/etc/man_db.conf,就会更新该文件的atime
文件的时间很重要,因为,如果文件的时间错误的话,可能会造成某些程序无法顺利运行。比如安装系统时系统时区不正确,那么系统文件也会和系统时间保持一致,将系统时区改为正确时区后,这些系统文件的时间就是错误的了。如果发现一个文件来自未来,可以使用touch将该文件变为现在时刻。
-f force,强制删除,忽略不存在的文件,不会出现瞥吉信息
-r 递归删除,用于删除目录
rm -rf test* 强制删除test开头的文件或目录
删除-开头的文件或目录[tips]:
因为-是命令的选项参数,所以在删除-开头的文件或目录时系统会误判,所以要是加上文件的路径,如:rm ./-aaa- 表示删除当前目录下的-aaa-文件,或rm 文件的绝对路径。此方法同样适用于任何touch、cp、mv...等命令。或者使用rm -- -aaa-来删除-aaa-文件。
删除空目录,若目录不为空则无法删除
rmdir [OPTION]... DIRECTORY...
-p 递归删除
rmdir -p test1/test2/test3/test4 #使用-p选项,立刻可将test1/test2/test3/test4 多层目录一次性删掉,但是rmdir仅能删除空目录
tips: 文件正在被使用,使用rm -f也无法删除
1.复制文件、目录
2.建立链接文件(快捷方式)
3.比较两个文件的新旧而子以更新
Usage: cp [OPTION]... [-T] SOURCE DEST
or: cp [OPTION]... SOURCE... DIRECTORY 源文件有多个时,目标文件一定是目录
or: cp [OPTION]...-t DIRECTORY SOURCE...
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
常见参数:
-p 连同文件的属性(权限、所属用户、时间) 一起复制过去,而非使用默议属性(常用于备份〉
-r 递归复制,用于目录的复制
-d 若源文件为链接文件的属性,则复制链接文件属性,而非文件本身
-f 强制,目标文件存在时使用此参数强制复制
-i 若目标文件已经存在时,在覆盖时会先询问操作是否要继续,y为确定,n为取消
-1 进行硬链接 (hard link),而非复制文件本身
-s 进行符号链接 (symbolic link),亦即创建快捷方式
-a 相当于-dr --preserver=a11,复制源文件的所有属性,使源文件和目标文件一模一样
--preserver=a11 除了复制-p的权限相关属性外,SELinux的属性,Links、xattr等属性也一同复制过去
-u 目标文件比源文件旧或目标文件不存在时才复制,常用于备份
在默认条件中,cp的源文件与目标文件的权限是不同的,目标文件的拥有者和所属组通常是使用cp命令的人。
knowledge: 符号链接和硬链接
1.移动文件、目录
2.重命名
Usage: ls [OPTION]... [FILE]... 可以接多个文件或目录,同时列出这些文件或目录
常见参数
-1 列出目录和文件的详细信息
[root@centos79 ~]# 1s -1 bak/
total 24
drwxr-xr-x 2 root root 18 Nov 27 17:48 bak1
-rwxr--r-- 1 root root 70 Oct 29 17:50 cpujiance.sh
-rw-r--r-- 1 root root 4384 Oct 29 17:50 cpu.txt
-rW-r--r-- 1 root root 1638 Oct 29 17:50 freel.txt
-rw------- 1 root root 10 oct 29 17:51 nohup .out
-rw-r--r-- 1 root root 11 Oct 29 17:51 sleep.sh
-d 仅列出目录本身,而不是列出目录内的文件
1s 目录:不会列出目录的数据,而是会列出目录内的文件的数据, 1s -d 目录:会列出目录本身的数据,而不是列出目录内的文件的数据
[root@centos79 ~]# 1s-1d bak/
drwxr-xr-x 3 root root 103 Nov 27 17:47 bak/
-R 连同子目录内容一起列出来
[root@centos79 ~]# 1s -lR bak/
bak/:
total 24
drwxr-xr-x 3 root root 30 Nov 27 17:55 bak1
-rwxr--r-- 1 root root 70 Oct 29 17:50 cpujiance.sh
-rw-r--r-- 1 root root 4384 Oct 29 17:50 cpu.txt
-rw-r--r-- 1 root root 1638 Oct 29 17:50 free1.txt
-rw------- 1 root root 10 Oct 29 17:51 nohup.out
-rw-r--r-- 1 root root 11 Oct 29 17:51 sleep.sh
bak/bak1:
total 0
-rw-r--r-- 1 root root 0 Nov 27 17:48 bak2
drwxr-xr-x 2 root root 18 Nov 27 17:55 bak3
bak/bak1/bak3:
total 0
-rw-r--r-- 1 root root 0 Nov 27 17:55 bak4
-A 显示所有文件,包括隐藏文件(.开头),但不包括.和..这两个目录
-F 在文件或目录名字的结尾对其进行标记,*表示可执行文件,/表示目录,=表示socket文件,|表示FIFO文件。
1s -F | grep *$可以用来查找此目录中的可执行文件
-h 特文件容量以人类易读的方式(KB、GB)列出来,默认是以byte显示文件大小
--b1ock-size=G 以G显示文件大小
-i 列出inode号码
-n 用UID和GID品示来代替所属用户和所属群组
-S 以文件容量大小进行排序显示,默认是以文件名进行排序显示
-r 排序时翻转排序
-t 以时间排序显示,默认是以文件名进行排序显示
--color=never 不要依据文件特性给子颜色显示
--color=always 显示颜色
--color=auto 让系统自行依据设置来判断是否给予颜色显示
--fu11-time 以完整时间模式(包含年月日时分〉显示
--time=[atime,ctime] 输出access时间 (atime)或改变权限属性时间(ctime),而非内容修改时间(modification time)(默认显示的是内容修改时间mtime)
打印当前所在的目录(print working directory)
pwd -P 显示出真正的路径,而非使用链接(link)路径
hostnamect1 set-hostname NAME 设置主机-名,退出重新登陆后終端会显示设置的主机名
hostnamectl --help 查看更多用法
类似于hostnamectl
hostname -help查看更多用法
1.目标不存在(/root/test3和/root/test4/不存在的情况下):
1.1目标为文件
[root@centos79 ~]# cp /root/testhead /root/test3 #会将testhead复制一份,名字为test3
1.2目标为目录
[root@centos79 ~]# cp /root/testhead /root/test4/
cp: cannot create regular file '/root/test4/': Not a directory #复制失败
2.目标存在(/root/test5和/root/test6/存在的情况下):
2.1目标为文件
[root@centos79 ~]# cp /root/testhead /root/test5
cp: overwrite '/root/test5'? #提示test5已经存在,是否覆盖?
2.2目标为目录
[root@centos79 ~]# cp /root/testhead /root/test6/
[root@centos79 ~]# ll /root/test6
total 4
-rw-r--r--. 1 root root 15 Dec 1 10:56 testhead #会将/root/testhead复制一份到/root/test6/中,名字和源文件名字一致
1.目标不存在(/root/test3和/root/test4/不存在的情况下):
1.1目标为文件
[root@centos79 ~]# cp -r /root/testhead/ /root/test3
[root@centos79 ~]# ll
total 8
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
drwxr-xr-x. 2 root root 25 Dec 1 11:15 test3 #会将目录/root/testhead/及其子目录或子文件复制一份,名称为/root/test3/,子目录或子文件的名字和源文件保持一致。系统将/root/test3当做/root/test3/来处理
drwxr-xr-x. 2 root root 25 Dec 1 11:14 testhead
[root@centos79 ~]# ll test3/
total 4
-rw-r--r--. 1 root root 15 Dec 1 11:15 subtesthead
2.2目标为目录
[root@centos79 ~]# cp -r /root/testhead/ /root/test4/
[root@centos79 ~]# ll
total 8
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
drwxr-xr-x. 2 root root 25 Dec 1 11:15 test3
drwxr-xr-x. 2 root root 25 Dec 1 11:20 test4 #等价于cp -r /root/testhead/ /root/test4,效果见cp -r /root/testhead/ /root/test3
drwxr-xr-x. 2 root root 25 Dec 1 11:14 testhead
[root@centos79 ~]# ll test4
total 4
-rw-r--r--. 1 root root 15 Dec 1 11:20 subtesthead
2.目标存在(/root/test5和/root/test6/存在的情况下):
2.1目标为文件
[root@centos79 ~]# cp -r /root/testhead/ /root/test5
cp: cannot overwrite non-directory '/root/test5' with directory '/root/testhead/'
2.2目标为目录
[root@centos79 ~]# cp -r /root/testhead/ /root/test6/
[root@centos79 ~]# ll test6
total 0
drwxr-xr-x. 2 root root 25 Dec 1 11:30 testhead #将目录/root/testhead/复制到目录/root/test6/下,名字与源目录保持一致
[root@centos79 ~]# ll testhead/
total 4
-rw-r--r--. 1 root root 15 Nov 30 15:14 subtesthead
1.目标不存在(/root/test3和/root/test4/不存在的情况下):
1.1目标为文件
[root@centos79 ~]# mv /root/testhead /root/test3
[root@centos79 ~]# ll
total 12
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
-rw-r--r--. 1 root root 15 Nov 30 15:14 test3 #将/root/testhead改名为/root/test3
1.2目标为目录
[root@centos79 ~]# mv /root/testhead /root/test4/
mv: cannot move '/root/testhead' to '/root/test4/': Not a directory #/root/test4/不存在,无法移动
2.目标存在(/root/test5和/root/test6/存在的情况下):
2.1目标为文件
[root@centos79 ~]# mv /root/testhead /root/test5
mv: overwrite '/root/test5'? #提示test5已经存在,是否覆盖?
2.2目标为目录
[root@centos79 ~]# mv /root/testhead /root/test6/
[root@centos79 ~]# ll /root/test6
total 4
-rw-r--r--. 1 root root 15 Nov 30 15:14 testhead #会将/root/testhead移动到/root/test6/中,名字和源文件名字一致
1.目标不存在(/root/test3和/root/test4/不存在的情况下):
1.1目标为文件
[root@centos79 ~]# mv /root/testhead/ /root/test3
[root@centos79 ~]# ll
total 8
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
drwxr-xr-x. 2 root root 25 Dec 1 11:14 test3 #将目录/root/testhead/的名字修改为/root/test3/,系统将/root/test3当做/root/test3/来处理
[root@centos79 ~]# ll test3/
total 4
-rw-r--r--. 1 root root 15 Nov 30 15:14 subtesthead
1.2目标为目录
[root@centos79 ~]# mv /root/testhead /root/test4/
[root@centos79 ~]# ll
total 8
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
drwxr-xr-x. 2 root root 25 Dec 1 11:14 test4 #效果见mv /root/testhead/ /root/test3
[root@centos79 ~]# ll test4/
total 4
-rw-r--r--. 1 root root 15 Nov 30 15:14 subtesthead
2.目标存在(/root/test5和/root/test6/存在的情况下):
2.1目标为文件
[root@centos79 ~]# mv /root/testhead/ /root/test5
mv: overwrite '/root/test5'? y
mv: cannot overwrite non-directory '/root/test5' with directory '/root/testhead/' #不能将目录改名为文件
2.2目标为目录
[root@centos79 ~]# mv /root/testhead/ /root/test6/
[root@centos79 ~]# ll
total 8
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
-rw-r--r--. 1 root root 0 Dec 1 11:45 test5
drwxr-xr-x. 3 root root 22 Dec 1 11:48 test6 #将源目录及其子目录或子文件移动到目标目录中,目录名和源目录名保持一致
[root@centos79 ~]# ll test6
total 0
drwxr-xr-x. 2 root root 25 Dec 1 11:14 testhead
-A 相当于-vET,可列出一些特殊字符而不是空白
-b 列出行号,仅针对非空白行做行号显示,空白行不标行号
-n 列出行号,空白行也标出行号
-E 将结尾的换行符$ 显示出来
-T 将Tab(制表符)以^I显示出来
-v 列出一些看不出来的特殊字符
#使用tab和空格的效果差不多,都是一堆空白,使用-A选项可以看出空格和tab的区别,使用-A时空格就显示空格,tab则显示^I
#使用-A时,每一行的结尾都会显示$,因为在linux(Unix)中用$表示换行符,而在windows(DOS)中用^M$表示换行符
#cat后面不加任何选项和参数表示进入手动输入内容模式,即输入a后会立刻显示a,常配合数据流重定向(> >> < <<)使用,见> >> < <<小节的例4、例5、例6[tips]
Knowledge: windows(DOS)和linux(Unix)的换行符:
DOS中的换行符为^M$,^M称为CR符号,$称为LR符号,而linux下的换行符为LR符号,即$
如果将在DOS中编写的shell脚本直接放到linux上执行会报错,因为linux不认识CR符号,会把CR符号当做脚本内容来执行,所以需要将DOS文件中每一行的CR符号删掉后才能正常执行。或使用unix2dos或dos2unix命令进行转换(需要先安装dos2unix包)。或在vim中使用:set ff?查看文件格式,使用:set ff=nuix或:set ff=dos进行格式转换。
#由最后一行到第一行反向在屏幕上显示出来
[root@centos79 ~]# tac testhead
B C D
AA
[root@centos79 ~]# cat testhead
AA
B C D
#将输出的文件内容自动加上行号
-b t 如果有空行,空行不显示行号(默认)
-b a 如果有空行,空行显示行号,类似于cat -n
-n ln 行号在屏幕的最左端显示,空行显示行号
[root@centos79 ~]# nl -n ln testhead
1 AA
2 B C D
-n rn 行号前面不加0,空行显示行号
[root@centos79 ~]# nl -n rn testhead
1 AA
2 B C D
-n rz 行号前面加0,空行显示行号
[root@centos79 ~]# nl -n rz testhead
000001 AA
000002 B C D
-w 定义行号占用多少字符
[root@centos79 ~]# nl -w 10 -n rz testhead
0000000001 AA
0000000002 B C D
#一页一页显示
#按最后一行显示目前显示的百分比,还可以在最后一行输入一些有用的命令:
按回车 向下翻一行
按空格 向下翻一页
按b或ctrl+b 向上翻一页,该按键不支持由管道传进来的more输入
输入/字符串 在当前显示的屏幕界面向下查找“字符串”,可以使用正则表达式
输入:f 立即在最后一行显示文件名和目前显示的行数
按q 离开more
#less比more更具有弹性,man命令就是调用less来显示说明文件的内容
按回车 向下翻一行
按空格 向下翻一页
按pagedown 向下翻一页
按pageup 向上翻一页
输入/字符串 在当前显示的屏幕界面向下查找“字符串”,按n可以继续查找下一个,按N可以继续查找上一个,可以使用正则表达式
输入?字符串 在当前显示的屏幕界面向上查找“字符串”,按n可以继续查找下一个,按N可以继续查找上一个,可以使用正则表达式
按q 离开less
按g 跳转到第一页
按G 跳转到最后一页
#显示文件的前几行,默认显示前10行
Usage: head [OPTION]... [FILE]...
-n 后面接数字,代表显示前几行的意思
head -n 10 /etc/man_db.conf 显示/etc/man_db.conf的前10行
head -n -10 /etc/man_db.conf 只是不显示/etc/man_db.conf的后10行,其余全都显示
#显示文件的后几行,默认显示后10行
Usage: tail [OPTION]... [FILE]...
-n 后面接数字,代表显示后几行的意思
-f 持续刷新显示后面所接文件的内容,按下ctrl+c结束tail
head -n +100 /etc/man_db.conf 只是不显示/etc/man_db.conf的前100行,其余全都显示
tips: cat tac nl more less head tail命令只能用于查看纯文本文件,当使用上述命令查看非文本文件时会显示乱码。例如查看/usr/bin/passwd这个二进制可执行文件,所以查看非文本文件时要用od命令。
#查看非文本文件时要用od命令
-t 后面接各种文件类型。例如:
a 利用默认的字符来输出
c 使用ASCII字符来输出
d[size] 利用十进制来输出数据,每个整数占用size Bytes
f[size] 利用浮点数值来输出数据,每个整数占用size Bytes
o[size] 利用八进制来输出数据,每个整数占用size Bytes
x[size] 利用十六进制来输出数据,每个整数占用size Bytes
od -t c /usr/bin/passwd 将/usr/bin/passwd的内容使用ASCII方式显示
#[tips]
#查看字符对应的ASCII码
od -t oCc /usr/bin/passwd 将纯文本文件/etc/issue中内容以十进制列出,可以看出\的十进制ascii码为92,a的十进制ascii码为97
[root@centos79 ~]# od -t dCc /etc/issue
0000000 92 83 10 75 101 114 110 101 108 32 92 114 32 111 110 32
\ S \n K e r n e l \ r o n
0000020 97 110 32 92 109 10 10
a n \ m \n \n
0000027
#查看password这几个字母的十进制ascii码对照
[root@centos79 ~]# echo "password" | od -t dCc
0000000 112 97 115 115 119 111 114 100 10
p a s s w o r d \n
0000011
Usage: dos2unix [options] [file ...] [-n infile outfile ...]
-k 保留该文件原本的mtime时间格式
-n 保留原本的旧文件,将转换后的内容输出到新文件,如dos2unix -n oldfile newfile
1.将iso装载进光驱
2.挂载到某一目录,例如/mnt
mount /dev/cdrom /mnt
或
mount /dev/sr0 /mnt #/dev/cdrom是/dev/sr0的符号链接(快捷方式)
3.在挂载点查找rpm包
find /mnt -name *dos2unix*.rpm #在/mnt及其子目录下查找名字中包含dos2unix的rpm包
4.rpm -ivh /mnt/... #...为安装包所在路径
5.离开挂载目录,卸载挂载
cd /root && umount /mnt
修改文件或目录所属用户组
被修改的组名一定要在文件/etc/group中,否则修改时会报错
chgrp [-R] groupname dirname/filename...
-R 进行递归修改,亦即连同子目录下的所有文件、目录都更新成这个用户组之意,常常用在修改某一目录内的所有文件的情况
chgrp root testtouch #将testtouch的用户组改为root
修改文件或目录的拥有者
被修改的用户一定要在文件/etc/passwd中
chown [-R] 账号名称 文件或目录
chown [-R] 账号名称:用户组名称 文件/目录
或 chown [-R] 账户名称.用户组名称 文件/目录 #同时修改文件、目录的拥有者和用户组
-R 进行递归修改,亦即连同子目录下的所有文件都修改
chown bin testtouch #将testtouch的拥有者改为bin这个账户
chown root:root testtouch #将testtouch这个文件的拥有者改为root,所属用户组改为root
修改文件的权限
使用数字类型修改文件权限:
chmod [-R] xyz 文件/目录 xyz为rwx属性数值相加
-R 进行递归修改,亦即连同子目录下的所有文件/目录都会被修改
使用符号类型修改文件权限:
chmod u=rwx,go=rx testtouch
或chmod u=rwx,g=rx,o=rx testtouch #testtouch的拥有者(u)具有rwx的权限,所属组(g)和其他用户(o)具有rx的权限
chmod a=rwx testtouch
或chmod =rwx testtouch #省略a #testtouch的拥有者(u),所属组(g)和其他用户(o)均具有rwx的权限,a=all=ugo
chmod ug+rx,o+w testtouch
或chmod u+rx,g+rx,o+w #testtouch的拥有者(u),所属组(g)赋予rx的权限,其他用户(o)赋予w的权限
chmod a+x testtouch
chmod +x #testtouch的拥有者(u),所属组(g),其他用户(o)赋予x的权限
chmod uo-rx testtouch
或chmod u-rx,o-rx testtouch #testtouch的拥有者(u),其他用户(o)减去rx的权限,所属组(g)的权限不变
chmod a-r testtouch
或chmod -r testtouch #testtouch的拥有者(u),所属组(g),其他用户(o)减去rx的权限
knowledge
[root@centos79 ~]# ll
total 12
-rw-------. 1 root root 1669 Nov 29 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 22 Dec 1 10:24 bin
-rw-r--r--. 1 root root 1896 Nov 29 17:16 initial-setup-ks.cfg
drwx--x--x. 2 root root 6 Dec 3 04:25 test1
-rwxr-xr-x. 1 root root 9 Dec 3 04:54 testtouch
第一栏属性:
第一列:d表示目录,-表示文件,l表示链接文件,b表示设备文件里面可供存储的周边设备(可按块随机读写的设备),c表示设备文件里面的串行端口设备,例如键盘、鼠标(一次性读取设备)
第2-4列:
文件拥有者的权限
5-7列:
加入此用户组的账号对此文件/目录拥有的权限
8-10列:
非本人且没有加入本用户组的其他账号的权限
第二栏属性:
表示有多少文件名链接到此节点(inode),如果为目录,则第二栏显示的就是此目录里文件/目录的数量,这里显示的数量减去2(.和..)即为此目录实际拥有的文件/目录数量,也就是对目录而言,这一栏属性的值至少为2。[tips]
第三栏属性:
表示这个文件/目录的拥有者账号
第四栏属性:
表示这个文件/目录的所属用户组
第五栏属性:
这个文件/目录的容量大小,默认为Bytes
第六栏属性:
这个文件/目录的创建日期或最近修改内容的日期,这一栏的内容格式为:月 日 时:分,但是如果这个文件被修改的时间距离现在太远,则这一栏的显示格式为:月 日 年
第七栏属性:
文件/目录的名称,.开头的表示隐藏文件/目录
knowledge
文件的rwx权限:
r:可读取此文件的实际内容,如读取文本文件的文字内容
w:可以编辑、新增该文件的内容
x:该文件具有可以被系统执行的权限
在windows中,判断一个文件是否具有执行的能力是借由扩展名来判断的,例如exe、bat等。而在linux中,文件能否被执行,则借由是否具有x这个权限来决定,和文件名是没有绝对的关系
目录的rwx权限:
r:可以查询该目录下的文件名数据,如使用ls列出来
w:具有可以改动该目录结构列表的权限:1.建立新的文件和目录;2.删除已经存在的文件与目录(不论该文件的权限是什么);3.将已存在的文件或目录进行更名;4.移动该目录内的文件、目录位置。
x:可以进入该目录,即可以cd到该目录
如果你在某目录下不具有x权限时,那么你就无法切换到该目录下,即使你具有该目录的r或w权限,也无法执行该目录下的任何命令(具有r权限时,可以在该目录的父目录中执行ls命令查看该目录的文件/目录列表)。
如果你在某目录下不具有r权限时,那么你就无法对该目录使用ls,即使你拥有w或x权限
如果你在某目录下不具有w权限时,那么你对该目录下的文件/目录不具有删除、修改权限、移动、改名、新建的权限,但是可以对该目录下的文件的内容进行修改,因为能否修改文件内容取决于文件本身的权限,和文件所在目录的权限无关。[tips]
knowledge: inode
umask #显示目前用户建立文件或目录时的权限的默认值需要减掉的权限
#目录和文件的默认权限不一样,x权限对于目录是非常重要的,但一般文件的建立则不应该具有执行的权限,因为一般文件通常用于数据的记录,当然不需要执行的权限。因为建立文件的默认权限为666,建立目录的默认权限为777。 [tips]
0022
#0022表示建立目录的默认权限为:拥有者权限:(rwx)-(---)(0)=rwx 所属用户组权限:(rwx)-(-w-)(2)=r-x 其他用户权限:(rwx)-(-w-)(2)=r-x [tips]
#0022表示建立文件的默认权限为:拥有者权限:(rw-)-(---)(0)=rw- 所属用户组权限:(rw-)-(-w-)(2)=r-- 其他用户权限:(rw-)-(-w-)(2)=r-- [tips]
umask -S #以符号类型的方式来显示权限
u=rwx,g=rx,o=rx
Set Uid
当s这个标志出现在文件拥有者的x权限位置时,如
[root@centos79 ~]# ll /bin/passwd
-rwsr-xr-x. 1 root root 69744 Apr 6 2020 /bin/passwd
此时该文件Set Uid,即该文件具有SUID的特殊权限
SUID权限的限制和功能:
SUID权限仅对二进制程序有效(SUID权限不能用在目录上,同样也不能用在shell脚本上面,因为shell脚本只是调用多个二进制可执行文件罢了,shell脚本本身不属于二进制程序);
执行者对该二进制程序需要具有可执行权限;
SUID权限仅在执行该二进制程序的过程中有效(run-time);
执行者将具有该二进制程序拥有者的权限,即执行者相当于该文件的拥有者,在该二进制程序执行过程中,该文件拥有者能rwx的文件,执行者同样可以rwx。
例1:
在linux中,所有账号的密码都记录在/etc/shadow这个文件中,使用passwd命令会将新密码写入到该文件中,该文件的权限为----------. 1 root root 1204 Nov 29 17:01 /etc/shadow,即这个文件只有root账号可以强制读取和写入,既然这个文件仅有root可以修改,那么一般账号为什么同样可以使用passwd命令修改自己的密码呢?
答:
passwd的权限为 -rwsr-xr-x. 1 root root 69744 Apr 6 2020 /bin/passwd
其他用户(如dmtsai账号)对该文件具有执行的权限,即其他用户(如dmtsai账号)可以执行该文件。而该二进制程序的拥有者是root这个账号,根据SUID的权限可知,当执行者(如dmtsai账号)执行此二进制程序时,执行者(如dmtsai账号)暂时获得root的权限,即执行者(如dmtsai账号)可以暂时对/etc/shadow文件进行读取和修改[Tips]。
例2:
如果dmtsai用户使用cat去读取/etc/shadow时,它能读取到吗?
答:
不能,因为cat的权限为 -rwxr-xr-x. 1 root root 71040 Apr 26 2020 /bin/cat
cat这个二进制程序不具有SUID的权限,所以dmtsai用户执行cat命令时不会获得root的权限,即对/etc/shadow文件不可读取和修改。为/bin/cat设置SUID权限后可以使用其他用户cat /etc/shadow
Set GID
当s标志在文件/目录的用户组的x位置时,称为Set GID(SGID)
[root@centos79 ~]# ll /usr/bin/locate
-rwx--s--x. 1 root slocate 76352 May 11 2019 /usr/bin/locate
SGID可以作用于文件,也可以作用于目录。
作用于文件时,SGID具有如下的功能:
SGID对二进制可执行文件有用;
执行者对该二进制可执行文件需要具有可执行权限;
执行者在执行此二进制程序的过程中会获得该程序所属用户组的权限
例:
/usr/bin/locate这个程序可以去查找/var/lib/mlocate/mlocate.db这个文件的内容,mlocate.db的权限如下:
-rw-r-----. 1 root slocate 2984292 Dec 1 13:50 /var/lib/mlocate/mlocate.db
与SUID类似,如我用dmtsai这个账号去执行locate时,那dmtsai将会取得slocate用户组的权限,因此dmtsai具有权限去读取mlocate.db,但是不能修改,因为slocate用户组对mlocate.db只有r的权限
作用于目录时,SGID具有如下的功能:
用户若对于此目录具有r与x的权限时,该用户能够进入此目录;
用户在此目录下的有效用户组将会变成该目录所属的用户组;
用途:若用户在此目录下具有w的权限(可以新建文件),则用户所建立的新文件,该新文件的所属用户组与此目录的所属用户组相同。
详细用法见:p207 情景模拟题 [tips]
Sticky Bit
当t标志在目录的其他用户的x位置时,称为Sticky Bit(SBIT)
SBIT仅对目录有效
[root@centos79 ~]# ll -d /tmp
drwxrwxrwt. 13 root root 4096 Dec 3 18:34 /tmp
SBIT的功能:
当用户对于此目录具有wx权限时,即具有写入的权限;
当用户在该目录下建立文件或目录时,仅有用户自己与root用户才有权限删除该文件或目录。
例:
/tmp本身的权限是 drwxrwxrwt. 13 root root 4096 Dec 3 18:34 /tmp
从/tmp的权限可知,任何人对该目录均具有rwx的权限,即任何人都可以在/tmp内新增、修改文件/目录,但是仅有该文件/目录的建立者与root能都删除该文件/目录。
4为SUID,2为SGID,1为SBIT
假设一个文件的权限为-rwxr-xr-x,要为此文件添加SUID权限时,在原先的755之前加上一个4即可,即chmod 4755 filename或chmod u+s filename或chmod u=rwxs,go=rx filename
st和ST的区别[tips]:
当SUID/SGID/SBIT取代x这个权限时,文件/目录的权限显示为s和t,比如:
[root@centos79 ~]# ll -d test1
drwxr-xr-x. 2 root root 6 Dec 3 04:25 test1
[root@centos79 ~]# chmod 7755 test1
[root@centos79 ~]# ll -d test1
drwsr-sr-t. 2 root root 6 Dec 3 04:25 test1
当文件/目录不具有x权限时,设置SUID/SGID/SBIT权限时,文件/目录的权限显示为S和T,比如:
[root@centos79 ~]# ll -d test1
drw-r-xr--. 2 root root 6 Dec 3 04:25 test1
[root@centos79 ~]# chmod ug+s,o+t test1
[root@centos79 ~]# ll -d test1
drwSr-sr-T. 2 root root 6 Dec 3 04:25 test1
显示文件隐藏属性 list attribute
lsattr [-adR] 文件或目录
-a 将隐藏文件的属性也显示出来
-d 如果接的是目录,仅列出目录本身的属性而非目录内的文件名
-R 连同子目录的数据也一并列出来
[root@centos79 ~]# chattr +aiS testtouch
[root@centos79 ~]# lsattr testtouch
--S-ia-------------- testtouch
设置文件的隐藏属性 change attribute
chattr [+-=][ASacdistu] 文件或目录名称
ext2,ext3,ext4的文件系统上对上述选项完整生效,xfs文件系统仅支持AadiS选项
+ 增加某一个特殊参数,其他原本存在参数则不动
- 删除某一个特殊参数,其他原本存在参数则不动
= 直接设置参数,且仅有后面接的参数
A 当设置了A这个属性时,若你在存取此文件(或目录)时,它的存取时间atime将不会被修改,可避免I/O较慢的机器过度的读写磁盘,目前建议使用文件系统挂载参数处理这个项目
S 一般文件是非同步写入磁盘的(即对文件修改后,修改后的文件还在内存中,过段时间才会存入到磁盘中,可以使用sync命令强制将内存中数据写入到磁盘中[tips]),如果加上S这个属性时,当你进行任何文件的修改,该修改会同步写入到磁盘中。
a 当设置a之后,这个文件将只能增加数据,而不能删除也不能修改数据,只有root才能设置这个属性(常用,常作用于日志文件)
c 这个属性设置后,将会自动的将此文件压缩,在读取时将会自动解压缩,但是在存储的时候,将会先进行压缩后再存储(对大文件有用)
d 当dump程序被执行的时候,设置d属性的文件/目录将不会被dump备份
i 可以让一个文件不能被删除、改名、设置链接、无法写入或新增数据,对于系统安全性具有相当大的益处,只有root能设置此属性(常用)
s 当文件设置了s属性时,如果该文件被删除,它将会被完全的从硬盘中删除,所以如果误删,完全无法恢复
u 与s相反,当使用u来配置文件时,如果该文件被删除了,则数据内容其实还在硬盘中,可以恢复该文件
find [PATH] [option] [action] #PATH表示PATH目录及其子目录,find后面可以接多个路径,find命令可以使用通配符来查找,但是find比较耗硬盘和内存(搜索整个硬盘,查找速度慢)
1.与时间相关的选项,有:-atime,-ctime,-mtime,以-mtime为例
-mtime n n为数字,表示在n天之前的【一天之内】被修改过内容的文件
-mtime +n 列出在n天之前(不含n天本身)被修改果内容的文件
-mtime -n 列出在n天之前(含n天本身)被修改果内容的文件
-newer file file为一个存在的文件,列出比file还要新的文件
#例1:将过去系统上面24小时内有修改过的内容的文件列出
find / -mtime 0 #0表示当前时间,所以从现在开始到24小时前,有变动过内容的文件都会被显示
find / -mtime 3 #3天前那一天的24小时内有变动过内容的文件都会被显示
find / -mtime -4 #找出4天内被修改过内容的文件
#例2:寻找/etc下面的文件,如果文件日期比/etc/passwd新就列出来
find /etc -newer /etc/passwd
2.与文件拥有者或文件所属用户组有关的参数:
-uid n n为数字,这个数字是文件拥有者的账号id,亦即UID
-gid n n为数字,这个数字是用户组id,亦即GID
-user name name为文件拥有者账号的名称
-group name name为用户组名称
-nouser 查找文件的拥有者不在/etc/passwd中
-nogroup 查找文件的拥有用户组不存在于/etc/group中
#例3:查找系统中不属于任何人的文件
find / -nouser #通过这个命令可以找出不正常的文件
3.与文件权限及名称有关的参数
-name filename 查找文件名称为filename的文件
-size [+-size] 查找比size还要大(+)或小(-)的文件。size的规格有:c代表Bytes,k代表1024Bytes,M代表1024*1024Bytes所以要找比50kb还要大的文件就是-size +50k
-type Type 查找文件的类型为type的文件,类型主要有:一般正规文件(f),设备文件(b、c),目录(d),链接文件(l),socket(s),FIFO(p)
-perm mode 查找文件权限刚好等于mode的文件,例如-rwsr-xr-x的mode等于4755
-perm -mode 查找文件权限等于或大于mode的文件,例如-perm -0744,则-rwxr--r--,亦即权限为0744的文件会被列出来,权限为-rwsr-xr-x的文件也会被列出来,因为-rwsr-xr-x的权限包含-rwxr--r--的权限
-perm /mode 查找文件权限包含任一mode的权限的文件,例如,查找-rwxr-xr-x,亦即-perm /755时,但一个文件属性为-rw-------也会被列出来,因为-rwxr-xr-x权限包含-rw-------
#例4:找出系统中文件名为passwd的文件
find / -name passwd #/表示在根目录及其目录(即所有目录中)查找
find / -name "*passwd*" #找出系统中文件名包含passwd的文件
#例5:找出/run目录下,文件类型为socket的文件有哪些
find /run -type s
#例6:找出包含SGID,SUID或SBIT权限的文件
find / -perm /7000 #7000就是---s--s--t,那么只要含有s或t的文件就列出,所以当然要使用/7000,使用-7000表示要同时含有---s--s--t权限的文件,如果只需要任意一个,就是/7000
#例7:找出系统中大于1M的文件
find / -siz +1M
4.额外可进行的操作
-exec command command为其他命令,-exec后面可以再接额外的命令来处理查找到的结果
-print 将结果打印到屏幕上,这个操作是默认的操作
#例8:将查找到的文件使用ls -l列出来
find /usr/bin /usr/sbin -perm /7000 -exec ls -l {} \; #-exec 后面接的ls -l就是额外的命令,命令不支持使用别名,所以仅能使用ls -l,不能使用ll,且-exec后面必须要直接接命令,不能用双引号或单引号将命令括起来。
#{}表示接收find找到的内容,即find找到的结果会被放置到{}中
#结尾处的;表示命令到这里结束,即-exec和;之间的都是额外的命令,即本例中的ls -l {},因为在bash中;符号用来连接两个命令,所以这里的;要用反斜杠来转义
#在特定的目录中查找文件,主要从/bin/sbin /usr/share/man中查找(速度快)
whereis [options] 文件或目录名
-l 列出whereis会去哪些目录中查找文件
-b 只查找binary(二进制)格式的文件
-m 只查找说明文件(manual)路径下的文件
-s 只查找source源文件
-u 查找除上述三个选项外的其他特殊文件
[root@centos79 ~]# whereis ifconfig
ifconfig: /usr/sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz #由ifconfig可以看出:whereis可以查找可执行文件;由ifconfig.8.gz可以看出:whereis可以查找非可执行文件,whereis在查找时会忽略文件后缀来查找[tips]
#从已建立的数据库/var/lib/mlocate/中查找(速度快),locate默认是模糊查找。缺点:locate数据库默认每天更新一次,当你新建立起来的文件,却在数据库更新前查找该文件,那么locate会找不到,此时可以使用updatedb命令来手动更新locate数据库,updatedb命令会读取/etc/updatedb.conf这个配置文件的设置,然后再去硬盘中进行查找文件名的操作,最后就是更新/var/lib/mlocate/内的数据库文件,因为updatedb会去查找硬盘,所以执行updatedb时可能会耗时几分钟[tips]
locate [options] keyword
-i 忽略大小写
-c 不输出文件名,仅计算找到的文件数量
-l 仅输出几行的意思
-S 输出locate所使用的的数据库文件的相关信息,包括该数据库记录的文件/目录数量等
-r 后面可接正则表达式
#找出系统中所有与passwd相关的文件名,且只显示5个
[root@centos79 ~]# locate -l 5 passwd
/etc/passwd
/etc/passwd-
/etc/pam.d/passwd
/etc/security/opasswd #模糊查找,只要包含passwd就会显示出来
/usr/bin/gpasswd
point:在linux中,只要可执行的文件可以被称为命令,而放在$PATH变量中的可执行文件可以理解为全局命令或系统命令(任意路径下均可执行的命令),which和type只能查找到全局命令/系统命令。
#which用来显示$PATH目录下的可执行文件的完整路径,即用来查找命令的所在之处。若which查找的文件虽然在$PATH目录下,但是此文件是非可执行文件,那么which会找不到。可以使用通配符。
which [-a] command
-a 将所有由$PATH目录中可以找到的命令均列出,而不止第一个被找到的命令名称
#例1:找出包含test的命令
[root@centos79 ~]# which *test*
/usr/bin/test
/root/bin/testhead
#不能使用双引号或单引号将命令括起来
[root@centos79 ~]# which '*tes*'
/usr/bin/which: no *tes* in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
[root@centos79 ~]# which "*tes*"
#例2:查找history命令
/usr/bin/which: no *tes* in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
[root@centos79 ~]# which history
/usr/bin/which: no history in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
#因为which是查找$PATH路径下的可执行文件,而history是bash内置的命令,history命令不在$PATH目录下,所以which会找不到
#查询命令是内置于bash中还是来自外部(来源:linux默认安装或用户手动安装)
type [-afptP] name [name ...]
不加任何选项时,type会显示name是外部命令还是bash内置命令
-t 当加入-t选项是,type将name以下面这些字眼显示出它的意义:file表示外部命令,alias表示该命令为命令别名所设置的名称,builtin表示该命令为bash内置的命令功能,并不能根据加上-t选项运行出的结果来判断是否内bash内置命令,详见例2
-p 当name为file(外部)命令时才会显示命令的完整路径,并不能根据加上-p选项运行出的结果来判断是否内bash内置命令,详见例2
-a 会由PATH变量定义的路径中,将所有含有name的命令都列出来,包括alias
#例1:
[root@centos79 ~]# type ls
ls is aliased to `ls --color=auto` #不加任何参数,列出ls的最主要使用情况
#例2:
[root@centos79 ~]# type -t ls
alias #仅列出ls执行时的依据,不能根据alias来判断ls是外部命令还是内bash内置命令,因为bash内置命令起别名后,使用type -t并不会显示builtin,而是显示alias,例如:为history设置别名:alias history=’history -w‘,运行type -t history会显示alias。同样地,也不能使用type -p命令来判断是否是外部命令,为history起别名后,type -p ls和type -p history均不会打印出命令的完整路径。想要判断,命令是否是bash内置命令,需要使用type -a,只要type -a显示的结果中包含builtin,那么这个命令就是内置命令[tips]
#例3:
[root@centos79 ~]# type -a ls
ls is aliased to `ls --color=auto` #执行ls命令时,最先使用alias
ls is /usr/bin/ls #列出了ls的具体路径,所以ls是外部命令
knowledge: 命令运行顺序(优先级由高到低排序)
1.以相对/绝对路径执行的命令,例如[/bin/ls]或[./ls]
2.由alias找到该命令来执行
3.由bash内置的(builtin)命令来执行
4.通过$PATH这个变量的顺序查找到的第一个命令来执行
例:执行/bin/ls结果没有颜色,而执行ls有颜色,因为/bin/ls是直接使用该命令来执行,而ls会因为[alias ls='ls --color=auto']这个别名而先使用。可以通过type -a ls来查看命令的执行顺序[tips]。
alias用来设置命令别名
alias 别名='命令 选项...'
alias的定义规则与变量的定义规则几乎相同,命令的别名和变量的区别:alias是新创一个新的命令,你可以直接执行该命令,变量则是需要使用 echo命令来打印出变量的内容[tips]
alias 不加选项,列出当前设置的别名
常用的别名:
alias lm='ls -al | more'
alias cls='clear'
alias dir='mkdir'
alias h='history'
unalias用来取消别名
unalias 别名 删除别名
tips: 在命令前加上\,可以忽略掉alias的指定选项
[root@centos79 ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias 1.='ls -d .* --color=auto'
alias 11='1s -1 --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
默认为root身份的rm设置了alias:rm=' rm -i',root使用rm时会不断的询问是否要删除,可以使用\rm来忽略
alias
清空终端屏幕
查看曾经执行过的命令,即在命令行中按↑后显示的命令
history n n为数字,列出最近执行过的n条命令
history -c 将目前shell中所有的历史命令清除,清除后按↑不会显示执行过的命令
history -a 将目前新增的history命令新增入histfiles中,若没有加histfiles,则默认写入到~/.bash_history
history -r 将histfiles的内容读到目前这个shell的history记录中
history -w 将目前的history记录内容写入到histfiles中,在默认情况下,会将历史记录写入到~/.bash_history中
tips: 利用history来快速执行命令
[root@centos79 ~]# history
1 man rm
2 alias
3 man history
4 history
[root@centos79 ~]# !! #两个感叹号表示执行最近执行过的一条命令,即本例中的第4号命令:history
history
1 man rm
2 alias
3 man history
4 history
[root@centos79 ~]# !2 #执行第2条命令,即本例中的alias
alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
...
[root@centos79 ~]# !al #执行最近以al开头的命令,即本例中的第2条命令:alias
alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
...
knowledge:
历史命令的读取与记录:
1. 当我们以bash登录linux主机后,系统会主动地由家目录的~/.bash_history文件读取之前曾经执行过的命令,那么~/.bash_history会记录几条数据?这就与bash的HISTFILESIZE(或HISTSIZE)这个变量的设置值有关了,默认值为1000;
2. 假设我这次登录主机后,共执行过100次命令,那么等我注销时,系统就会将最近1000条命令更新到~/.bash_history中,当然也可以使用history -w强制立刻写入。
同一账号同时多次登录的history写入问题:
最后要注销的那个bash才会是最后写入的数据,如此一来,其他bash的命令操作命令就不会被记录下来了。
history无法记录时间问题:
解决办法见p360情景模拟题
knowledge: Bash shell(/bin/bash)是linux系统默认的shell,兼容于sh shell。。。p315
查看文件的基本信息:ASCII纯文本文件、数据文件、二进制文件、有没有使用到动态链接库(share library)
[root@centos79 ~]# file ~/.bashrc
/root/.bashrc: ASCII text #ASCII纯文本文件
[root@centos79 ~]# file /usr/bin/passwd
/usr/bin/passwd: setuid ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=0e33773b9a79d38fa12cc8150285caa6adb538f2, stripped #显示了passwd的SUID权限,兼容ARM aarch64,使用动态链接库
knowledge: linux系统常见的压缩文件扩展名
*.z compress程序压缩的文件
*.zip zip程序压缩的文件,windows常用压缩文件
*.gz gzip程序压缩的文件,,常用
*.bz2 bzip2程序压缩的文件,常用,压缩比好
*.xz xz程序压缩的文件,压缩比好
*.tar tar程序打包的文件,并没有压缩过。tar程序可以将很多文件/目录打包成一个文件,仅打包,不压缩。
*.tar.gz tar程序打包的文件,并且经过gzip程序压缩
*.tar.bz2 tar程序打包的文件,并且经过bzip2程序压缩
*.tar.xz tar程序打包的文件,并且经过xz程序压缩
compress 会将文件压缩成*.Z文件,已经被gzip命令取代
使用znew命令可以将.Z文件转为.gzip文件
gzip命令可以解开compress,zip,gzip等软件所压缩的文件,gzip所建立的压缩文件为*.gz,gz文件可以被windows中WinRAR或7zip等软件解压缩
gzip [-cdtv#] 文件名
-c 将压缩文件的数据输出到屏幕上,可以通过数据流重定向来处理
-d 解压缩的参数
-k 保留原始文件
-t 可以用来检验一个压缩文件的一致性,检查文件有无错误
-v 可以显示出原文件/压缩文件的压缩比信息
-# #为数字的意思,代表压缩等级,-1最快,但是压缩比最差,-9最慢,但是压缩比最好,默认是-6
例
[root@centos79 ~]# ls -ldS /etc/* | grep ^- | head -3 #找出/etc/下容量最大的三个文件
-rw-r--r--. 1 root root 692252 May 15 2020 /etc/services
-rw-r--r--. 1 root root 60352 May 11 2017 /etc/mime.types
-rw-r--r--. 1 root root 39403 Nov 29 17:14 /etc/ld.so.cache
[root@centos79 tmp]# cp /etc/services /tmp
[root@centos79 tmp]# gzip -v services #将services文件压缩
services: 79.4% -- replaced with services.gz
[root@centos79 tmp]# ll services* #默认情况下:services会被压缩成services.gz,并且源文件services将消失
-rw-r--r--. 1 root root 142528 Dec 4 01:44 services.gz
[root@centos79 tmp]# gzip -d services.gz #将services文件解压
[root@centos79 tmp]# ll services* #默认情况下:services.gz会被解压成services,并且源文件services.gz将消失
-rw-r--r--. 1 root root 692252 Dec 4 01:44 services
[root@centos79 tmp]# gzip -c services > services.gz #-c选项会将原本要转成压缩文件的数据内容,将它变成文字类型从屏幕输出。数据流>可以将原本应该有屏幕输出的数据,转成输出到文件而不是屏幕,所以两者配合就能够建立出压缩文件,并且保留源文件。
[root@centos79 tmp]# ll services*
-rw-r--r--. 1 root root 692252 Dec 4 01:44 services
-rw-r--r--. 1 root root 142528 Dec 4 01:55 services.gz
zcat/zmore/zless 用来读取纯文本文件被compress或gzip压缩后的压缩文件
zgrep 用来查找纯文本文件被compress或gzip压缩后的压缩文件中数据
bzip2是为了替换gzip命令,压缩比比gzip更好,用法类似于gzip
bzip2 [-cdkzv#] 文件名
-c 将压缩的过程产生的数据输出到屏幕上
-d 解压缩参数
-k 保留原始文件
-z 压缩的参数(默认,可以不加)
-v 可以显示出原文件/压缩文件的压缩比信息
-# #为数字的意思,代表压缩等级,-1最快,但是压缩比最差,-9最慢,但是压缩比最好,默认是-6
用法同zcat/zmore/zless/zgrep
xz是压缩比比bzip2更好,用法类似于gzip,bzip2
xz [-dtlkcv#] 文件名
-c 将压缩的过程产生的数据输出到屏幕上
-d 解压缩参数
-l 列出压缩文件的相关信息
-t 可以用来检验一个压缩文件的一致性,检查文件有无错误
-k 保留原始文件
-v 可以显示出原文件/压缩文件的压缩比信息
-# #为数字的意思,代表压缩等级,-1最快,但是压缩比最差,-9最慢,但是压缩比最好,默认是-6
例
[root@centos79 tmp]# xz -v services
services (1/1)
100 % 103.4 KiB / 676.0 KiB = 0.153
[root@centos79 tmp]# ll services*
-rw-r--r--. 1 root root 105872 Dec 4 01:44 services.xz
[root@centos79 tmp]# xz -l services.xz #列出services.xz的信息
Strms Blocks Compressed Uncompressed Ratio Check Filename
1 1 103.4 KiB 676.0 KiB 0.153 CRC64 services.xz
time 后面接命令,可以计算后面命令的执行时间
虽然gzip,bzip2,xz命令也能针对目录来进行压缩,不过这三个命令对目录的压缩指的是将目录内的所有文件分别进行压缩的操作,而不是将这个目录整体压缩。
tar命令可以将多个文件或目录打包成一个大文件*.tar,之后可以通过压缩命令对这个*.tar进行压缩。此外,windows中的WinRAR也支持对*.tar.gz文件的解压缩
仅打包不压缩的文件称为tarfile,打包并且压缩称为tarball
tar [-z|-j|-J] [cv] [-f 待建立的新文件名] filename(被打包的文件/目录)... #打包与压缩
tar [-z|-j|-J] [tv] [-f 既有的tar文件名] filename... #查看文件
tar [-z|-j|-J] [xv] [-f 既有的tar文件名] [-C 目录] #解压缩
-c -t -x不能出现在同一条命令中
-c 建立打包文件
-v 在压缩/解压的过程中吗,将正在处理的文件名显示出来
-t 查看打包文件的内容含有哪些文件
-x 解包或解压缩,可以配合-C 在特定的目录解压
-z 通过gzip的支持进行压缩/解压缩,此时文件名最好为*.tar.gz
-j 通过bzip2的支持进行压缩/解压缩,此时文件名最好为*.tar.bz2
-J 通过xz的支持进行压缩/解压缩,此时文件名最好为*.tar.xz
-f filename -f后面要立刻接要被处理的文件名
-C 目录 这个选项用在解压缩,若要在特定的目录中解压缩,可以使用此选项,如果不加-C,会默认在当前目录下解压缩
-p(小写) 保留备份数据的原本权限与属性,常用于备份重要的配置
-P(大写) 保留绝对路径,亦即允许备份数据中含有根目录存在之意,-P并没有保留备份数据的原本权限与属性的含义
--exclude=FILE 在压缩的过程中,不将文件FILE打包
例1
[root@centos79 /]# tar -zcvp -f /root/etc.tar.gz /etc/ | more #备份/etc/这个目录,-p表示保留原权限和属性(备份)
tar: Removing leading `/' from member names
/etc/
/etc/mtab
/etc/fstab
/etc/crypttab
...
[root@centos79 /]# tar -ztv -f /root/etc.tar.gz | more #查看/root/etc.tar.gz的内容
drwxr-xr-x root/root 0 2022-11-30 03:52 etc/
lrwxrwxrwx root/root 0 2022-11-29 16:58 etc/mtab -> ../proc/self/mounts
-rw-r--r-- root/root 742 2022-11-29 16:57 etc/fstab
-rw------- root/root 0 2022-11-29 16:57 etc/crypttab
drwxr-xr-x root/root 0 2022-11-29 16:57 etc/dnf/
... #使用-p(小写)备份会去掉根目录,目的:我们使用tar备份的数据可能会需要解压缩回来使用,tar包中所记录的文件名就是解压缩后的实际文件名,如果拿掉根目录,假设你将备份的数据在/tmp中解开,那么解压缩的文件名就会变成/tmp/etc/xxx。如果没有去掉根目录,解压缩后的文件名就会是绝对路径,即解压缩后的数据一定会被放置到/etc/xxx去,如此一来,你原本的/etc/下面的数据就会被备份的数据所覆盖.[tips]
[root@centos79 /]# tar -zcv -f /root/etc01.tar.gz /etc/ | more #不加-p选项,即仅打包压缩,不保留原属性和权限(备份),仍会移除根目录。所以移不移除根目录与-p选项无关,仅与-P选项有关[tips]
tar: Removing leading `/' from member names
/etc/
/etc/mtab
/etc/fstab
/etc/crypttab
/etc/dnf/
...
例2 仅解开单一文件
[root@centos79 ~]# tar -ztv -f /root/etc.tar.gz | grep "shadow" #在压缩包中查找shadow
-rw-r--r-- root/root 214 2021-03-24 01:20 etc/pam.d/sssd-shadowutils
---------- root/root 712 2022-11-29 17:01 etc/gshadow
---------- root/root 701 2022-11-29 16:59 etc/gshadow-
---------- root/root 1209 2022-11-29 17:01 etc/shadow-
---------- root/root 1204 2022-11-29 17:01 etc/shadow
[root@centos79 ~]# tar -zxv -f /root/etc.tar.gz etc/shadow #tar -zxv -f 打包文件 待解开的文件名
etc/shadow
[root@centos79 ~]# ll /root/etc/shadow
----------. 1 root root 1204 Nov 29 17:01 /root/etc/shadow
例3 假设我们想打包/etc和/root这两个目录,打包后的文件命名为/root/system.tar.bz2,打包时排除/root/etc*开头的文件,因为打包的目录包括/root,而打包后的文件/root/system.tar.bz2也在/root目录下面,所以打包时也要排除/root/system.tar.bz2这个文件,不然会自己打包自己
[root@centos79 ~]# tar -jcv -f /root/system.tar.bz2 --exclude=/root/etc* --exclude=root/system.tar.bz2 /etc /root
例3 仅备份比某个时刻还要新的文件,例如备份比/etc/passwd还要新的文件
[root@centos79 ~]# find /etc -newer /etc/passwd #找到比/etc/passwd这个文件的mtime还要新的文件
/etc
/etc/pki
/etc/pki/product
/etc/pki/product-default
/etc/ssh
/etc/ssh/ssh_host_ed25519_key
/etc/ssh/ssh_host_ed25519_key.pub
...
[root@centos79 ~]# ll /etc/passwd
-rw-r--r--. 1 root root 2229 Jun 17 00:20 /etc/passwd #passwd的mtime为2022 Jun 17 00:20
[root@centos79 ~]# tar -jcv -f /root/etc.newer.then.passwd.tar.bz2 --newer-mtime="2022/06/17" /etc/*
tar: Option --newer-mtime: Treating date '2015/06/17' as 2015-06-17 00:00:00
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
...
tar: /etc/yum.repos.d/bak/CentOS-Linux-PowerTools.repo: file is unchanged; not dumped
tar: /etc/yum.repos.d/bak/CentOS-Linux-Sources.repo: file is unchanged; not dumped #CentOS-Linux-Sources.repo没被备份的意思
...
例4 打包到磁带
tar -cv -f /dev/st0 /home /root /etc ...
例5 打包的同时解包,例如将/etc/ 整个目录一边打包一边在/tmp中解开,相当于将/etc复制到/tmp中[tips]
cd /tmp
tar -cvf - /etc | tar -xvf - #相当于cp -r /etc /tmp,-表示这个被打包的文件,由于我们不想让中间文件产生,所以使用-代替,-可以理解为内存中的一个设备(缓冲区)
-可以理解为内存中的一个设备(缓冲区)。 如果需要标准输入(stdin)或标准输出(stdout)时,但又没有文件,有的只是-时,那么这个-会被当成stdin或stdout,-既能被当成是stdin,又能被当做是stdout [tips]
dd
cpio
查看linux支持的文件系统
ls -l /lib/modules/$(uname -r)/kernel/fs
查看目前记载到内存中支持的文件系统
cat /proc/filesystems
将文件系统与目录树结合的操作叫做挂载,挂载点一定是目录,该目录为进入该文件系统的入口
挂载的注意事项:
1.单一文件系统不应该重复挂载在不同的挂载点
2.单一目录不应该重复挂载多个文件系统
3.被挂载的点应该是空目录,该目录被挂载后,里面的东西会暂时消失
mount
mount -a
mount -l
mount [-t 文件系统] LABEL='' 挂载点
mount [-t 文件系统] UUID='' 挂载点
mount [-t 文件系统] 设备名称 挂载点
-a 依照配置文件/etc/fstab的数据将所有未挂载的磁盘都挂载上来
-l 单纯的输入mount会显示目前挂载的信息,加上-l可以显示Label的名称
-t 可以加上文件系统的种类来指定欲挂载的类型(如果不加此选项,系统会自动分析最恰当的文件系统来尝试挂载设备),常见的Linux支持类型有:xfs、ext3、ext4、reiserfs、vfat、iso9660(光盘格式)、nfs、cifs、smbfs(后三种为网络文件系统类型)
-n 在默认的情况下,系统会将实际挂载的情况即使写入到/etc/mtab中,以里其他程序的运行,但是在某些情况下(如单人维护模式)为了避免问题,会使用-n来刻意不写到/etc/mtab中
-o 后面可以接一些挂载时的额外参数,如账号、密码、读写权限等:
async,sync:此文件系统是否使用同步写入(sync)或非同步(异步async)写入的内存机制,默认为async
atime,noatime:读取该文件系统的文件或目录时,是否会修改文件或目录的读取时间(atime),默认为atime,而某些时刻为了性能,会使用noatime
ro,rw:挂载文件系统成为只读(ro)或可读写(rw),默认为rw
auto,noauto:允许此文件系统被以mount -a自动挂载(auto)
dev,nodev:是否允许此文件系统可建立设备文件?dev为允许
suid,nosuid:是否允许此文件系统含有suid/sgid的文件格式
exec,noexec:是否允许此文件系统上拥有可执行二进制文件
user,nouser:是否允许此文件系统让任何使用者执行mount?一般来说mount仅root可以执行,但添加user参数,可以让一般user也能对次分区进行mount
defaults:默认值为:rw、suid、dev、exec、auto、nouser、async
remount:重新挂载,这在系统出错或重新更新参数时很有用
vers:
iocharset:
credentials:挂载网络文件系统时使用,指定认证文件的路径,其中认证文件的内容包含username='账号'(必须),password='密码'(必须)和domain='域'(可选)
codepage:
#含认证的两种挂载方式:[tips]
mount -t cifs -o credentials=/root/fs1.cred,ro,iocharset=gb2312,vers=2.0 //ip/share1 /fs1
mount -t cifs -o username=user,password=passwd,ro,deaults,vers=2.0 //ip/share2 /fs2
#重新挂载或更改已挂载的文件系统的参数
mount -o remount,rw,auto / #将/重新挂载,并加入参数rw和auto。场景:当你进入单人维护模式时,你的根目录常会被系统挂载为只读,这是就要重新挂载[tips]
#将某个目录挂载到另一个目录,相当于符号链接,当符号链接无效时可以使用此方法,例如将本地的目录与挂载的文件系统上的某个目录进行符号链接时会报failed to create symbolic link .... operation not supported的错误,此时可以使用mount进行目录与目录之间的挂载
mount --bind /var /data/var #将/var这个目录暂时挂在到/data/var下面
将挂载的文件系统卸载
umount [-fn] 设备文件名或挂载点
-f 强制卸载。可用在类似网络文件系统(NFS)无法读取到的情况下
-l 立即卸载文件系统,比-f还强
-n 不更新/etc/mtab的情况下卸载
#挂载点繁忙,无法卸载的情况
mount /dev/sr0 /data/cdrom
cd /data/cdrom
umount /data/cdrom
umount: /data/cdrom: target is busy #需要离开该文件系统的挂载点后再使用umount
...
cd /
umount /data/cdrom
列出文件系统的整体磁盘使用量
df主要读取的数据几乎都是针对一整个文件系统,因此读取的范围主要是在超级区块内的信息,所以df命令显示结果的速度非常快
df [-ahikHTm] [目录或文件名]
-a 列出所有的文件系统,包括系统特有的/proc等文件系统,系统中有许多特殊的文件系统存在,这些特殊的文件系统几乎都在内存中,例如/proc这个挂载点,因此这些特殊的文件系统都不会占据磁盘空间。
-k 以KBytes为单位显示各文件系统的容量
-m 以MBytes为单位显示各文件系统的容量
-h 以人类较易阅读为单位显示各文件系统的容量
-H 以M=1000k替换M=1024K的进位方式
-T 连同该硬盘分区的文件系统名称(例如xfs)也列出
-i 不用磁盘容量,而以inode的数量来显示。一个文件占用一个inode[tips]
[root@centos79 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.7G 0 1.7G 0% /dev
tmpfs 1.7G 0 1.7G 0% /dev/shm
tmpfs 1.7G 9.1M 1.7G 1% /run
tmpfs 1.7G 0 1.7G 0% /sys/fs/cgroup
/dev/mapper/vg00-root 10G 4.2G 5.9G 42% /
/dev/mapper/vg00-home 5.0G 80M 5.0G 2% /home
/dev/nvme0n1p2 1014M 244M 771M 25% /boot
/dev/nvme0n1p1 50M 6.8M 44M 14% /boot/efi
tmpfs 340M 0 340M 0% /run/user/0
/dev/sr0 6.8G 6.8G 0 100% /mnt
#Filesystem表示该文件系统是在哪个磁盘分区,即列出设备名称
#Size表示总容量
#Used 使用掉的磁盘空间
#Available 剩下的磁盘空间
#Use% 使用率
#Mounted on 磁盘的挂载目录(挂载点)
[root@centos79 ~]# df -h /etc 在df后面加上目录或是文件时,df会自动分析该目录或文件所在的磁盘分区,并将该磁盘分区的容量显示出来
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg00-root 10G 4.2G 5.9G 42% /
[root@centos79 ~]# df -a
Filesystem 1K-blocks Used Available Use% Mounted on
sysfs 0 0 0 - /sys
proc 0 0 0 - /proc #/proc的东西都是linux系统所需要加载的系统数据,会显示/proc的容量信息为0,proc文件系统都在内存中,因此该文件系统不会占据磁盘空间
devtmpfs 1677764 0 1677764 0% /dev
securityfs 0 0 0 - /sys/kernel/security
tmpfs 1739540 0 1739540 0% /dev/shm #/dev/shm目录是利用内存虚拟出来的磁盘空间,通常是物理内存容量二分之一,在这个目录下建立的任何数据,访问速度都非常快,但是该目录下建立的东西会在下次启动时消失。
devpts 0 0 0 - /dev/pts
tmpfs 1739540 9264 1730276 1% /run
tmpfs 1739540 0 1739540 0% /sys/fs/cgroup
cgroup 0 0 0 - /sys/fs/cgroup/systemd
pstore 0 0 0 - /sys/fs/pstore
efivarfs 0 0 0 - /sys/firmware/efi/efivars
none 0 0 0 - /sys/fs/bpf
cgroup 0 0 0 - /sys/fs/cgroup/net_cls,net_prio
cgroup 0 0 0 - /sys/fs/cgroup/freezer
cgroup 0 0 0 - /sys/fs/cgroup/blkio
cgroup 0 0 0 - /sys/fs/cgroup/cpu,cpuacct
cgroup 0 0 0 - /sys/fs/cgroup/devices
cgroup 0 0 0 - /sys/fs/cgroup/memory
cgroup 0 0 0 - /sys/fs/cgroup/cpuset
cgroup 0 0 0 - /sys/fs/cgroup/pids
cgroup 0 0 0 - /sys/fs/cgroup/perf_event
none 0 0 0 - /sys/kernel/tracing
configfs 0 0 0 - /sys/kernel/config
/dev/mapper/vg00-root 10475520 4334304 6141216 42% /
selinuxfs 0 0 0 - /sys/fs/selinux
systemd-1 - - - - /proc/sys/fs/binfmt_misc
debugfs 0 0 0 - /sys/kernel/debug
mqueue 0 0 0 - /dev/mqueue
hugetlbfs 0 0 0 - /dev/hugepages
fusectl 0 0 0 - /sys/fs/fuse/connections
/dev/mapper/vg00-home 5232640 81704 5150936 2% /home
/dev/nvme0n1p2 1038336 249328 789008 25% /boot
/dev/nvme0n1p1 51082 6878 44204 14% /boot/efi
tmpfs 347908 0 347908 0% /run/user/0
gvfsd-fuse 0 0 0 - /run/user/0/gvfs
binfmt_misc 0 0 0 - /proc/sys/fs/binfmt_misc
tracefs - - - - /sys/kernel/debug/tracing
/dev/sr0 7033408 7033408 0 100% /mnt
查看文件系统的磁盘使用量(常用在查看目录所占磁盘空间)
du -[ahskm] 文件或目录名称
-a 列出所有的文件与目录容量
-h 以人类易读的方式显示
-s 仅列出总量,而不列出每个各别的目录占用容量
-S 不包括子目录下的总计
-b 以Bytes为单位显示
-k 以KBytes为单位显示
-m 以MBytes为单位显示
[root@centos79 ~]# du #df 后面不接任何选项,会显示当前目录下的文件和目录所占用的磁盘空间,但是实际显示时,仅会显示目录容量(不含文件),因此当前目录下的文件没有被列出来,所以显示的目录容量相加不会等于当前目录下的总容量。
0 ./.cache/mesa_shader_cache
4 ./.cache/dconf
4 ./.cache
4 ./.dbus/session-bus
4 ./.dbus
0 ./.config/ibus/bus
0 ./.config/ibus
0 ./.config
4 ./bin
0 ./test1
4 ./etc
9516 .
[root@centos79 ~]# du -a #不接目录或文件时会显示当前目录下,以及子目录下的每个文件和目录的大小
4.0K ./.bash_logout
4.0K ./.bash_profile
4.0K ./.bashrc
4.0K ./.cshrc
4.0K ./.tcshrc
4.0K ./anaconda-ks.cfg
0 ./.cache/mesa_shader_cache/index
0 ./.cache/mesa_shader_cache
4.0K ./.cache/dconf/user #文件user的大小为4k
4.0K ./.cache/dconf #目录.cache/dconf的大小为4k,因为该目录下有文件user
4.0K ./.cache #目录.cache的大小为4k,因为该目录下有dconf,而目录dconf下有文件user
4.0K ./.dbus/session-bus/2dec64a1de7f4b84bfc20bb358a1c996-9
4.0K ./.dbus/session-bus
4.0K ./.dbus
0 ./.config/ibus/bus
0 ./.config/ibus
0 ./.config
4.0K ./initial-setup-ks.cfg
12K ./.bash_history
12K ./.viminfo
4.0K ./.lesshst
4.0K ./bin/testhead
4.0K ./bin
4.0K ./testtouch
0 ./test1
5.9M ./etc.tar.gz
4.0K ./etc/shadow
4.0K ./etc
3.4M ./etc.newer.then.passwd.tar.bz2
16K ./doc
9.3M . #当前目录的大小,相当于du -s
[root@centos79 ~]# du -s /* #查看根目录下每个目录所占用的容量,不会显示该目录下文件的大小
0 /bin
215738 /boot
0 /dev
28676 /etc
12000 /home
0 /lib
0 /lib64
0 /media
7027795 /mnt
0 /opt
du: cannot access '/proc/14472/task/14472/fd/4': No such file or directory #因为/proc中的内容是在内存中,因此会报这个错误
du: cannot access '/proc/14472/task/14472/fdinfo/4': No such file or directory
du: cannot access '/proc/14472/fd/4': No such file or directory
du: cannot access '/proc/14472/fdinfo/4': No such file or directory
0 /proc
9512 /root
9264 /run
0 /sbin
0 /srv
0 /sys
952 /tmp
3940344 /usr
162432 /var
[root@centos79 ~]# du -s / #查看根目录所占用的容量,包括该目录下的目录和文件
du: cannot access '/proc/14473/task/14473/fd/4': No such file or directory
du: cannot access '/proc/14473/task/14473/fdinfo/4': No such file or directory
du: cannot access '/proc/14473/fd/3': No such file or directory
du: cannot access '/proc/14473/fdinfo/3': No such file or directory
11406713 /
文件名只与目录有关,文件内容与inode有关
硬链接:在某个目录下新增一条文件名链接到某inode号码的关联记录。
硬链接的限制:
1.不能跨文件系统
2.不能链接目录
符号链接(快捷方式):建立一个独立的文件,这个文件会让数据的读取指向它链接的那个文件的文件名
ln [-sf] 源文件 目标文件
-s 如果不加任何参数就进行链接,那就是硬链接,加上-s就是符号链接
-f 如果目标文件存在时,就主动的将目标文件直接删除后再建立
例1 将/etc/passwd复制到/tmp下面,观察inode与区块
[root@centos79 tmp]# cp -a /etc/passwd /tmp/
[root@centos79 tmp]# du -sb;df -i ./
952679 . #/tmp目录的大小为952679Bytes
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/vg00-root 5242880 118142 5124738 3% /
例2 将/tmp/passwd制作硬链接称为passwd-hd文件,并查看文件与容量
[root@centos79 tmp]# ln passwd passwd-hd
[root@centos79 tmp]# du -sb;df -i ./
952679 . #即使在/tmp目录下多了一个文件passwd-hd,整个inode与区块的容量并没有改变。原因:硬链接只是在某个目录下的区块中多写入了一个关联数据而已,只要增加这个这条关联数据不会将目录的区块填满,就不会消耗区块数量,也不会增加inode[tips]
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/vg00-root 5242880 118142 5124738 3% /
[root@centos79 tmp]# ll -i passwd*
25918286 -rw-r--r--. 2 root root 2229 Nov 29 17:01 passwd #这两个文件指向同一个inode:25918286,此时第三栏的链接数变为2
25918286 -rw-r--r--. 2 root root 2229 Nov 29 17:01 passwd-hd
#例3 将/tmp/passwd 建立一个符号链接
[root@centos79 tmp]# ln -s passwd passwd-so
[root@centos79 tmp]# ll -i passwd*
25918286 -rw-r--r--. 2 root root 2229 Nov 29 17:01 passwd
25918286 -rw-r--r--. 2 root root 2229 Nov 29 17:01 passwd-hd
25918283 lrwxrwxrwx. 1 root root 6 Dec 5 23:55 passwd-so -> passwd #passwd-so指向的inode number不同了,这是一个新文件,这个文件的内容指向passwd这个文件,passwd-so的大小为6Bytes,因为【passwd】这个单词共有六个字符,在UTF-8编码表中,每个英文字符占1Bytes,每个汉字占3个字节[tips]
[root@centos79 tmp]# du -sb;df -i .
952685 . #已用容量增加了6Bytes
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/vg00-root 5242880 118143 5124737 3% / #已用inode增加了1
例4 删除原始文件/tmp/passwd,其他两个文件是否能够开启
[root@centos79 tmp]# rm -rf passwd
[root@centos79 tmp]# cat passwd-hd #硬链接可以正常开启
root:x:0:0:root:/root:/bin/bash
...
[root@centos79 tmp]# cat passwd-so
cat: passwd-so: No such file or directory #符号链接无法正常开启
[root@centos79 tmp]# ll passwd*
-rw-r--r--. 1 root root 2229 Nov 29 17:01 passwd-hd #链接数变为1
lrwxrwxrwx. 1 root root 6 Dec 5 23:55 passwd-so -> passwd
例5 将/bin与/tmp/bin建立符号链接 [tips:目录名称后加/和不加/的区别]
[root@centos79 tmp]# ln -s /bin/ /tmp/bin
[root@centos79 tmp]# ll bin #bin后面不加/时,列出bin这个目录本身[tips]
lrwxrwxrwx. 1 root root 5 Dec 6 00:12 bin -> /bin/
[root@centos79 tmp]# ll bin/ #bin后面加/时,列出bin这个目录中的文件[tips]
total 242224
-rwxr-xr-x. 1 root root 953736 Dec 22 2020 WebKitWebDriver
lrwxrwxrwx. 1 root root 4 Dec 11 2020 X -> Xorg
-rwxr-xr-x. 1 root root 273 Dec 11 2020 Xorg
-rwxr-xr-x. 1 root root 2629952 Dec 16 2020 Xvnc
-rwxr-xr-x. 1 root root 2383480 Dec 11 2020 Xwayland
...
[root@centos79 tmp]# rm bin #删除/tmp/bin这个链接文件[tips]
rm: remove symbolic link 'bin'? y
[root@centos79 tmp]# ll bin
ls: cannot access 'bin': No such file or directory
[root@centos79 tmp]# rm bin/ #bin后面加上/时,表示删除/tmp/bin这个链接文件指向的原目录/bin,所以在删除链接时一定要用rm 链接文件,不能用rm -r 链接文件[tips]
rm: cannot remove 'bin/': Is a directory
knowledge:变量的规范
1.双引号内的特殊字符可以保持原本的特性,如:var="lang is $LANG",则echo $var可得lang is zh_CN.UTF-8
2.单引号内的特殊字符则仅为一般字符,如:var='lang is $LANG',则echo $var可得lang is $LANG
3.=号两边不能有空格,如下所示为错误:var = Lang is或var=Lang is,当变量中有空格时,可以使用双引号或单引号括起来
4.在一串命令中,还需要借由其他额外的命令所提供的信息时,可以使用返单引号`命令`或$(命令),如version=$(uname -r) [tips]
5.若该变量为扩增变量内容时,则可以用 "$变量名称"累加内容 或 ${变量}累加内容,如:PATH="$PATH":/home/bin或 PATH=${PATH}:/home/bin [tips]
6.若该变量需要在其他子程序中执行时,需要使用export命令来时使该变量变为环境变量,如export PATH,注意:变量名称前不能加$ [tips]
7.通常用大写字母命令的变量名为系统默认变量,自行设置变量可以使用小写字母
8.取消变量的命令为unset 变量名称,如unset name,注意:变量名称前不能加$
9.可以使用转义符\来将特殊字符转换为一般字符,如:将空格和'转换为一般字符:var=john\'s\ hat\ is\ black. [tips]
knowledge:环境变量
$PATH:当我们执行一个命令时,如ls,系统会依照PATH的设置去每一个PATH定义的目录下查找文件名为ls的可执行文件,如果PATH定义的目录中含有多个文件名为ls的可执行文件,那么先查找的同名命令先被执行。echo $PATH可以打印目前的PATH,PATH这个变量由一堆目录所组成,每个目录用冒号:来分隔,每个目录有顺序之分,不同身份用户默认的PATH不同。将/root目录添加到到PATH中,PATH=”${PATH}:/root“,将“本目录”加入到PATH中,PATH="${PATH}:.",加入后在当前目录中使用testtouch就能执行[tips],而不用使用./testtouch,为了安全,最好不要把.放到PATH中。
$HOME:代表用户的根目录,cd ~或cd回到家目录就是使用的这个变量
$SHELL:目前环境使用的shell程序是哪个,默认为/bin/bash,即使用bash命令后会再开启一个子bash shell
$LANG:语系数据,当我们在启动有些perl的程序语言文件时,它会主动地分析语系数据文件,如果发现有它无法解析的编码语系,可能会产生错误。中文常用语系为zh_CN.GB2312或zh_CN.UTF-8
$RANDOM:随机数的变量,大多数linux发行版本都会有随机数生成器,也就是/dev/random这个文件,我们可以通过这个随机数文件相关的变量$RANDOM来随机获取一个随机数,在bash shell环境下,这个随机数的介于0-32767之间。如果想获取0-9之间的随机数,可以使用declare声明数值类型,如declare -i number=$RANDOM*10/32768;echo $number [tips]
$$:当前shell的PID
将自定义变量(自定义变量不能被子进程引用)转换为环境变量(环境变量可以被子进程引用),
export 变量名称 #将变量名称转换为环境变量,如export var
列出环境变量
export
[root@centos79 tmp]# export
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/0/bus"
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
...
env是environment的缩写,env可以列出目前shell环境下的所有环境变量及其内容
root@centos79 tmp]# env
LS_COLORS=rs=0:di=38;5;33:ln=38;5;51:mh=00:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9...... #一些颜色设置
SSH_CONNECTION=192.168.1.8 52609 192.168.1.9 22 #本机ip 本机通讯端口 目标ip 目标通讯端口
LANG=zh_CN.UTF-8 #当前shell的语系
HISTCONTROL=ignoredups
HOSTNAME=centos79 #主机名
OLDPWD=/root #上一个工作目录的所在
XDG_SESSION_ID=44
USER=root #使用者的名字
SELINUX_ROLE_REQUESTED=
PWD=/tmp #当前使用者所在的工作目录,使用pwd命令获取
HOME=/root #使用者的家目录
SSH_CLIENT=192.168.1.8 52609 22
SELINUX_LEVEL_REQUESTED=
XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
SSH_TTY=/dev/pts/0
MAIL=/var/spool/mail/root #目前使用者所用的邮件位置
TERM=xterm-256color #终端使用的环境是什么类型
SHELL=/bin/bash #目前这个环境下,使用的shell是哪一个程序
SELINUX_USE_CURRENT_RANGE=
SHLVL=1
LOGNAME=root #使用者用来登录的账号名称
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
XDG_RUNTIME_DIR=/run/user/0
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin #命令查找路径
HISTSIZE=1000 #记录历史命令的条数,centos默认为1000条
LESSOPEN=||/usr/bin/lesspipe.sh %s
_=/usr/bin/env #上一次使用的命令的最后一个参数(或命令本身)
列出所有变量(环境变量和自定义变量)
[root@centos79 tmp]# set | more
BASH=/bin/bash
BASH_VERSINFO=([0]="4" [1]="4" [2]="19" [3]="1" [4]="release" [5]="aarch64-redhat-linux-gnu")
BASH_VERSION='4.4.19(1)-release' #这两行是bash的版本
COLUMNS=157 #在目前的终端环境下,使用的栏位有几个字符长度
HISTFILE=/root/.bash_history #历史命令记录的放置文件 [tips]
HISTFILESIZE=1000 #/root/.bash_history中存放的命令最大数
HISTSIZE=1000 #内存中记录的历史命令最大条数
HOSTTYPE=aarch64 #cpu架构
IFS=$' \t\n' #默认的分隔符 [tips]
LINES=43 #目前终端下的最大行数 [tips]
OSTYPE=linux-gnu #操作系统的类型
PS1='[\u@\h \W]\$ ' #命令提示字符,也就是常见的[root@centos79 tmp]# [tips]
PS2='> ' #第二行的命令提示符,即:ls -a\按回车后的命令提示符 [tips]
$ #当前shell的PID
? #刚刚执行完命令的返回值,执行成功则返回0,出错则返回非0 [tips]
...
[root@centos79 tmp]# locale
LANG=zh_CN.UTF-8 #主语言的环境
LC_CTYPE="zh_CN.UTF-8" #字符辨识的编码
LC_NUMERIC="zh_CN.UTF-8" #数字系统的显示信息
LC_TIME="zh_CN.UTF-8" #时间系统的显示信息
LC_COLLATE="zh_CN.UTF-8" #字符的比较与排序
LC_MONETARY="zh_CN.UTF-8" #货币格式的显示
LC_MESSAGES="zh_CN.UTF-8" #信息显示的内容,如功能表,错误信息等
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL= #整体语系的环境,要让LC_ALL生效,需要使用export将其转为环境变量才行
#如果其他语系变量未被设置,但是设置了LC_ALL或LANG的值,那么其他语系变量的值会被LC_ALL或LANG的值替换 [tips]
#整体系统默认的语系定义在/etc/locale.conf里面 [tips]
读取来自键盘输入的变量,与用户交互
read [-pt] variable
-p 后面可以接提示字符,-p选项默认不带换行的功能,且也不支持\n换行,但是通过$'String'的方式特殊处理,就可以实现换行的功能。例 如:read -p $'Enter your name: \n'
-t 后面可以接等待的【秒数】
-e 加上-e后,用户在输入的时候可以使用左右键来调整光标位置,如果不加此选项,输入过程中按左右键会出现^[[C^[[D
-r 此选项可以屏蔽\,如果没有此选项,则\会作为一个转义字符,添加此选项后\就是一个正常的字符了。如果不加-r,输入的内容中含有\时,会默 认将\删掉,-r选项用于输入windows的路径时很有效。
[root@centos79 ~]# read atest
This is a test #此时光标会等待用户输入,输入完成后按enter
[root@centos79 ~]# echo $atest
This is a test
[root@centos79 ~]# read -p "Please keyin your name:" -t 30 named
Please keyin your name:VBird Tsai
[root@centos79 ~]# echo named
VBird Tsai
声明变量的类型
declare [-aliep] variable
declare后面如果不接任何内容,则会列出所有的变量名称和变量内容,类似set
变量类型默认为字符串
-p 列出变量variable的类型
-a 将后面名为variable的变量定义成数组(array)类型
-i 将后面名为variable的变量定义成整数(integer)类型
-x 效果和export命令相同,将后面的variable变成环境变量
-r 将变量设置成为readonly类型,该变量不可被更改内容,也不能被unset
例1 让变量sum进行100+300+50的求和结果
[root@centos79 ~]# sum=100+300+50
[root@centos79 ~]# echo $sum
100+300+50
[root@centos79 ~]# declare -i sum=100+300+50
[root@centos79 ~]# echo $sum
450
例2 将sum变为环境变量
[root@centos79 ~]# declare -x sum
[root@centos79 ~]# export | grep sum
declare -ix sum="450"
[root@centos79 ~]# set | grep sum
sum=450
例3 让sum变成非环境变量的自定义变量
[root@centos79 ~]# declare +x sum #将-x变为+x,可以进行取消操作 [tips]
[root@centos79 ~]# declare -p sum
declare -i sum="450"
例4 数组类型的变量设置 [tips]
[root@centos79 ~]# var[1]=a
[root@centos79 ~]# var[2]=b
[root@centos79 ~]# var[3]=3
[root@centos79 ~]# echo ${var[1]} ${var[2]} ${var[3]}
a b 3
ulimit:user limit
限制用户的某些系统资源使用,如:可以开启的文件数量,可以使用的cpu时间,可以使用的内存容量等
ulimit [-SHacdfltu] [配额]
-H hard limit,严格的设置,必定不能超过这个设置的数值
-S soft limit,警告的设置,可以超过这个设置的数值,但是若超过则会有警告
-a 后面不接任何选项与参数,可以列出所有限制的额度
-c 当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件(排错用),这种文件就被称为内核文件(core file)。此选项为限制每个内核文件的最大容量
-f 此shell可以建立的最大文件容量(一般设置为2GB),单位为KBytes
-d 程序可使用的最大段内存(segment)容量
-l 可用于锁定(lock)的内存量
-t 可使用的最大CPU时间,单位为秒
-u 单一使用者可以使用的最大进程(process)数
[root@centos79 ~]# ulimit -a
core file size (blocks, -c) unlimited #0或unlimited表示没限制
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited #可建立的单一文件的大小为:无限制
pending signals (-i) 13107
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024 #同时可开启的文件数量为1024个
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 13107
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
例 限制使用者仅能建立10MB以下的文件
[root@centos79 ~]# ulimit -f 10240
[root@centos79 ~]# ulimit -a | grep 'file size'
core file size (blocks, -c) unlimited
file size (blocks, -f) 10240 #最大为10MB
[root@centos79 ~]# dd if=/dev/zero of=123 bs=1M count=20
File size limit exceeded (core dumped) #尝试建立20MB的文件,结果失败了
标准输出(STDOUT)指的是命令执行所返回的正确信息,标准错误输出(STDERR)指的是命令执行失败后返回的错误信息
标准输入(stdin):代码为0,使用<或<<将标准输入重定向,<表示将原本需要由键盘输入的数据,改为文件内容来替换,<<表示【结束的输入字符】,见【例4】
标准输出(stdout):代码为1,使用1>或1>>将标准输出重定向,其中1可以省略[tips],即1>等价于>,1>>等价于>>。1>表示以覆盖的方式将【正确的数据】输出到指定的文件或设备上,若文件不存在则自动创建;1>>表示以累加的方式将【正确的数据】输出到指定的文件或设备上,若文件不存在则自动创建。注意:1和>之间没有空格。
标准错误输出(stderr):代码为2,使用2>或2>>将标准错误输出重定向。2>表示以覆盖的方式将【错误的数据】输出到指定的文件或设备上,若文件不存在则自动创建;2>>表示以累加的方式将【错误的数据】输出到指定的文件或设备上,若文件不存在则自动创建。注意:2和>之间没有空格。
例1 查找/home目录下名为.bashrc的文件,并将正确输出数据存到list_right中,错误的输出数据存到list_error中
[root@centos79 ~]# find /home -name .bashrc > list_right 2> list_error
例2 查找/home目录下名为.bashrc的文件,并将正确输出数据显示到屏幕上,错误的输出数据丢弃
[root@centos79 ~]# find /home -name .bashrc 2> /dev/null #/dev/null表示垃圾桶黑洞设备,此设备会将导入的任何信息全部吃掉
/home/dmtsai/.bashrc
例3 查找/home目录下名为.bashrc的文件,将正确输出数据和错误的输出数据统统存到list_all文件中[tips]
[root@centos79 ~]# find /home -name .bashrc > list_all 2> list_all #错误,由于两股数据同时写入一个文件,又没有使用特殊语法,此时两股数据可能会交叉写入该文件内,造成次序的错乱,所以虽然最终list_all文件还是会产生,但是里面的数据排列会怪怪的,而不是原本屏幕上的输出排序[tips]
[root@centos79 ~]# find /home -name .bashrc > list_all 2>&1 #正确
[root@centos79 ~]# find /home -name .bashrc &> list_all #正确
例3.1 将echo "error message"以标准错误的格式来输出
[root@centos79 ~]# echo "error message" 1>&2
error message
例4 利用cat命令来建立一个文件的简单流程[tips]
[root@centos79 ~]# cat > catfile
testing
cat file test
<==这里按下ctrl+d来退出
[root@centos79 ~]# cat catfile #将我们键盘输入的文字存入到了catfile
testing
cat file test
例5 用文件的内容来代替键盘的敲击,以建立新文件[tips]
[root@centos79 ~]# cat > catfile < ~/.bashrc
[root@centos79 ~]# ll catfile ~/.bashrc #这两个文件的大小一模一样
-rw-r--r--. 1 root root 176 May 11 2019 /root/.bashrc
-rw-r--r--. 1 root root 176 Dec 18 08:11 catfile
[root@centos79 ~]# cat catfile #catfile的内容和.bashrc的内容完全一样
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
例6 当键盘输入eof时结束输入[tips]
[root@centos79 ~]# cat > catfile << "eof" #<< 后面接【结束输入字符】,即当键盘输入eof后,该次输入就结束
> this is a test
> OK now stop
> eof #输入这个关键字,立刻结束而不需要输入ctrl+d
[root@centos79 ~]# cat catfile
this is a test
OK now stop
stdin、stdout、stderr的应用场景:[tips]
1.屏幕输出的信息很重要,而且我们需要将它存下来的时候(stdout/stderr)
2.后台执行中的程序,不希望它干扰屏幕正常的输出结果时(stdout/stderr)
3.一些系统的计划任务(如crontab)的执行结果,希望它可以保存下来时(stdout/stderr)
4.一些执行命令的可能已知错误信息时,想以【2> /dev/null】将它丢掉时(stdout/stderr)
5.错误信息与正确信息需要分别输出时(stdout/stderr)
6.将文件的内容代替键盘的键入,如使用mail命令时(stdin)
; 不考虑命令相关性的连续命令执行:
命令;命令;命令
sync;sync;shutdown -h now
&& || 考虑命令相关性的连续命令执行:
cmd1&&cmd2
若cmd1执行完毕且正确执行($?=0),则开始执行cmd2
若cmd1执行完毕且错误($?≠0),则不执行cmd2
cmd1||cmd2
若cmd1执行完毕且正确执行($?=0),则不执行cmd2
若cmd1执行完毕且错误($?≠0),则开始执行cmd2
例1 不清楚/tmp/abc是否存在,但是要建立/tmp/abc/hehe文件
ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe
#上述命令的执行顺序:若/tmp/abc不存在故返回$?≠0,则因为||遇到非0的$?故开始执行mkdir /tmp/abc,由于mkdir /tmp/abc会成功执行,所以返回$?=0,因为&&遇到$?=0故会继续执行继续执行touch /tmp/abc/hehe,最终hehe就被建立了。若/tmp/abc存在故返回$?=0,因为||遇到等于0的$?不会继续执行||后面的命令。此时$?=0继续向后传,故因为&&遇到$?=0就开始建立/tmp/abc/hehe了,最终/tmp/abc/hehe被建立
例2 判断/tmp/abc是否存在,若存在则打印exist,若不存在则打印not exist
ls /tmp/abc && echo "exist" || echo "not exist"
不能写成:
ls /tmp/abc || echo "not exist" && echo "exist"
#上述命令的执行顺序:若/tmp/abc不存在,则会执行echo "not exist",因为echo "not exist"肯定会执行成功,所以会继续执行echo "exist"
#所以,一般来说,假设判断是有三个,则命令通常为:command1 && command2 || command3 [tips]
管道命令|仅能处理经由前面一个命令传来的正确信息,也就是标准输出的信息,对于标准错误的信息并没有直接处理的能力,即
command1|command2|command3表示,command1的STDOUT作为command2的STDIN,command2的STDOUT作为command3的STDIN,最后显示command3的STDOUT或STDERR
command2和command3必须是管道命令(即能接受标准输入数据的命令)
常见管道命令:less more head tail cut grep sort wc uniq tee tr col join paste expand split xargs awk sed
如果要让标准错误也能被管道命令所使用,可以通过2>&1命令来使标准错误(2>)变为标准输出(1>) [tips]
选取命令就是将一段数据经过分析后,取出我们所想要的,或经由分析关键词,取得我们所想要的那一行。选取信息通常是针对一行一行来分析的,并不是整篇信息分析 [tips]
cut命令可以将一段信息的某一段给它切出来,得到我们想要的信息。处理的信息是以【行】为单位的
cut -d '分隔字符' -f fields #用于有特定分隔字符 [tips]
cut -c 字符区间 #用于排列整齐的信息 [tips]
-d 后面接分隔字符,与-f一起使用
-f 根据-d的分隔字符将一段信息划分成为数段,用-f取出第几段的意思
-c 以字符为 单位取出固定字符区间
例1 取出PATH变量中的第五个路径
[root@centos79 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos79 ~]# echo $PATH | cut -d ':' -f 5
/root/bin
[root@centos79 ~]# echo $PATH | cut -d ':' -f 3,5 #取出第3个和第5个路径
/usr/sbin:/root/bin
[root@centos79 ~]# echo $PATH | cut -d ':' -f 3-5 #取出第3个到第5个路径
/usr/sbin:/usr/bin:/root/bin
例2 将export输出的信息,取出第12个字符以后得所有字符
#因为export的输出是排列整齐的信息,如果我们不想要declare -x时,可以使用cut -c
[root@centos79 ~]# export | cut -c 12- #取出第12到20个字符则为cut -c 12-20,取出12个字符之前的字符则为cut -c -12
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/0/bus"
HISTCONTROL="ignoredups"
HISTSIZE="1000"
HOME="/root"
HOSTNAME="centos79"
LANG="zh_CN.UTF-8"
LESSOPEN="||/usr/bin/lesspipe.sh %s"
LOGNAME="root"
...
例3 取出last命令中的登录用户的用户名
[root@centos79 ~]# last | cut -d " " -f 1
root
root
reboot
root
root
...
grep分析一行信息,若当中有我们需要的信息,就将该行拿出来
grep -[acinv] [--color=auto] '查找字符' filename #查找字符可以为正则表达式
-a 将二进制文件以文本文件的方式查找数据
-c 计算找到'查找字符'的此书
-i 忽略大小写
-n 顺便输出行号
-v 反向选择,亦即显示出没有 '查找字符' 内容的那一行
--color=auto 将找到的关键字部分加上颜色显示,centos7中,grep已经主动使用 --color=auto选项在alias中了
-A 后面接数字,为after的意思,除了列出该行外,后面的n行也列出来
-B 后面接数字,为before的意思,除了列出该行外,前面的n行也列出来
例1 将last当中,有出现root的那一行显示出来
[root@centos79 ~]# last | grep 'root'
例2 将last的输出信息中,找出含有root的那一行,并且取出root
[root@centos79 ~]# last | grep 'root' | cut -d ' ' -f1
例3 列出reboot的那行,及前两行和后三行
[root@centos79 ~]# last | grep -A 3 -B 2 'reboot'
例4 找出/etc/rsyslog.conf中非空白且不是井号开头的数据
[root@centos79 ~]# grep -v '^$' /etc/rsyslog.conf | grep -v '^#'
例5 找出g后面接2到5个o,后面再接一个g的字符串
[root@centos79 ~]# grep 'go\{2,5\}g' regular_express.txt
#因为{}在shell中有特殊的意义,因此我们必须使用转义符\来让它失去特殊意义才行。如果某个符号在shell变成环境中有特殊意义,比如{},那么在正则表达式中如果需要使用{},就要用\转义。.在shell中没有特殊的含义,所以可以在正则表达式中直接使用,不用加\,但是如果正则表达式中.表示文本中的内容,则要使用\转义。[tips]
sort命令根据不同的数据形式排序
sort [-fbMnrtuk] [file or stdin]
-f 忽略大小写的差异
-b 忽略最前面的空格字符部分
-M 以月份的名字来排序,例如JAN、DEC等
-n 使用纯数字进行排序(默认是以文字形式来排序的)
-r 反向排序
-u 就是uniq,相同的数据中,仅出现一行代表
-t 分隔符号,默认是用tab键(制表符)来分隔
-k 以哪个区间(field)来进行排序的意思
例1 将/etc/passwd中的数据排序显示
[root@centos79 ~]# cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
chrony:x:991:984::/var/lib/chrony:/sbin/nologin
clevis:x:986:979:Clevis Decryption Framework unprivileged user:/var/cache/clevis:/sbin/nologin
cockpit-ws:x:993:986:User for cockpit web service:/nonexisting:/sbin/nologin
... #sort默认是以第一个信息的首字母来排序的
例2 按:分隔,并以第三栏来排序
[root@centos79 ~]# cat /etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash #0
dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash #10
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin #11
operator:x:11:0:operator:/root:/sbin/nologin #11
games:x:12:100:games:/usr/games:/sbin/nologin
... #将第三栏看成字符串来进行排序
例3 按:分隔,把第三栏看成数字,并根据第三栏来排序 [tips]
[root@centos79 ~]# cat /etc/passwd | sort -t ':' -k 3 -n
root:x:0:0:root:/root:/bin/bash
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
...
wc命令可以列出文件中有多少字,多少行,多少字符
wc [-lwn]
什么选项都不加表示列出有多少字,多少行,多少字符
-l 仅列出多少行
-w 仅列出多少字
-m 仅列出多少字符
例1
[root@centos79 ~]# cat /etc/man_db.conf | wc
131 721 5165 #131表示/etc/man_db.conf有131行,721表示/etc/man_db.conf有721个字,5165表示/etc/man_db.conf中有5165个字符
例2 查看系统中有多少个账号
[root@centos79 ~]# cat /etc/passwd | wc -l
40
uniq命令可以让重复的数据仅显示一个
uniq [-ic]
-i 忽略大小写
-c 进行计数
例1 使用last将账号列出,进取出账号栏,进行排序后仅从重复的内容中取出一行
[root@centos79 ~]# last | cut -d ' ' -f1 | sort | uniq
dmtsai
reboot
root
wtmp
例2 使用last将账号列出,进取出账号栏,进行排序后仅从重复的内容中取出一行,并列出重复的数据有多少个
[root@centos79 ~]# last | cut -d ' ' -f1 | sort | uniq -c
1 #空白的这一行和最后一行wtmp是last的默认字符,可以忽略
1 dmtsai
4 reboot
46 root #46表示last中root共出现了46次,即root登录了46次[tips]
1 wtmp
>>和>会将数据流整个传送给文件或设备,因此我们除非去读取该文件或设备,否则就无法继续利用这个数据流,万一我想要将这个数据流的处理过程中将某段信息存下来,就需要使用双向重定向命令tee,tee会同时将数据流分送到文件和屏幕,而输出到屏幕的,其实就是stdout
tee可以让stdout转存一份到文件并将这个stdout继续送到屏幕去处理,这样除了可以让我们同时分析一份数据并记录下来之外,还可以作为处理一份数据的中间缓存记录之用,即tee会同时将数据流分送到文件和屏幕
tee [-a] file
-a 以累加的方式将数据加入到file中,如果不加-a,那么tee后面接的文件会被覆盖掉
[root@centos79 ~]# last | tee last.list | cut -d ' ' -f1 #该命令会将last的内容输出一份存到./last.list文件中,然后将last的内容传给cut -d ' ' -f1
[root@centos79 ~]# ls -l /home | tee ~/homefile | more #将ls的数据存一份到~/homefile,同时屏幕也有输出信息
[root@centos79 ~]# ls -l / | tee -a ~/homefile | more #累加到~/homefile中
tr可以用来删除一段信息当中的文字,或是进行文字信息的替换,常用来替换文件中的怪异符号
tr [-ds] SET1 ... 可以使用正则表达式
不加任何选项表示:tr SET1 SET2表示用SET2来替换SET1
-d 删除信息当中的SET1这个字符
-s 替换掉重复的字符
例1 将last输出的信息中,所有的小写变成大写
[root@centos79 ~]# last | tr '[a-z]' '[A-Z]'
例2 在/etc/passwd输出的信息中,将冒号删除
[root@centos79 ~]# cat /etc/passwd | tr -d ':'
例3 删除doc换行文件中^M符号,并存为新文件
[root@centos79 ~]# cat ~/passwd | tr -d '\r' > ~/passwd.linux #\r指的就是DOS的换行符[tips]
col是标准输入文本过滤器,常用来将文本中的[tab]替换成空格键
col [-xb]
-x 将tab键替换为对等的空格键
-b 不输出任何退格符,在每列的位置上只打印最后写的那个字符
例
[root@centos79 ~]# cat /etc/man_db.conf | col -x | cat -A | more
expand用于将[tab]按键转成空格键
expand [-t] file
-t 后面可接数字,一般来说一个tab按键可以用8个空格键来替换,此选项可以定义一个tab按键代表多少个空格
例1
[root@centos79 ~]# grep '^MANPATH' /etc/man_db.conf | head -n 3 | cat -A
MANPATH_MAP^I/bin^I^I^I/usr/share/man$
MANPATH_MAP^I/usr/bin^I^I/usr/share/man$
MANPATH_MAP^I/sbin^I^I^I/usr/share/man$
[root@centos79 ~]# grep '^MANPATH' /etc/man_db.conf | head -n 3 | expand -t 6 - | cat -A
MANPATH_MAP /bin /usr/share/man$
MANPATH_MAP /usr/bin /usr/share/man$
MANPATH_MAP /sbin /usr/share/man$
例2
将空格转为tab
处理两个相关的数据文件,如果这两个文件中有相同数据的那一行,就将它们加在一起
/etc/passwd和/etc/shadow以账号为相关性, /etc/group与/etc/shadow以GID为相关性 [tips]
注意:使用join之前,所处理的文件应该要事先经过排序(sort) [tips]
join [-ti12] file1 file2
-t join默认以空格符分割数据,并且比对【第一个栏位】的数据,如果两个文件的【第一个栏位】的数据8相同,则将两条数据连成一行,且第一个栏位放在第一个
-i 忽略大小写
-1 代表【第一个文件要用哪个栏位来分析】的意思
-2 代表【第二个文件要用哪个栏位来分析】的意思
例1 将/etc/passwd和/etc/shadow相关数据整合成一栏
[root@centos79 ~]# head -n 3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
==> /etc/shadow <==
root:$6$nrs0dBveBSd3P.Lt$pH9Lt3jvS0.yndIhsA2q.OApegOtgyGpfJUca4cQG523ldbkmNsXMDQBmIA2IQvP0piQY.17miuXQLBKp1zLe/::0:99999:7:::
bin:*:18397:0:99999:7:::
daemon:*:18397:0:99999:7::: #由上述数据可以发现这两个文件的最左边栏都是相同的账号,且以:分割
[root@centos79 ~]# join -t ':' /etc/passwd /etc/shadow | head -n 3
root:x:0:0:root:/root:/bin/bash:$6$nrs0dBveBSd3P.Lt$pH9Lt3jvS0.yndIhsA2q.OApegOtgyGpfJUca4cQG523ldbkmNsXMDQBmIA2IQvP0piQY.17miuXQLBKp1zLe/::0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:18397:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:18397:0:99999:7:::
#通过上面的这个操作,我们可以将两个文件第一栏位相同者整合成一行
#第二个文件的相同栏位并不会显示,因为已经在最左侧的栏位出现了
例2 我们知道/etc/passwd第四个栏位是GID,这个GID记录在/etc/group的第三个栏位,如何将这个两个文件根据GID整合?
[root@centos79 ~]# head -n 3 /etc/passwd /etc/group
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
==> /etc/group <==
root:x:0:
bin:x:1:
daemon:x:2:
[root@centos79 ~]# join -t ':' -1 4 -2 3 /etc/passwd /etc/group | head -n 3
join: /etc/passwd:6: is not sorted: sync:x:5:0:sync:/sbin:/bin/sync
join: /etc/group:11: is not sorted: wheel:x:10:
0:root:x:0:root:/root:/bin/bash:root:x:
1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:
#同样的,相同栏位的部分被移动到了最前面,所以第二个文件的内容就没显示相同内容
join必须要比较两个文件的数据相关性,paste直接将两行粘在一起,且中间以tab分隔
paste [-d] file1 file2 ...
-d 后面可以接分隔字符,默认是以tab来分隔
- 如果file部分写成-,表示来自标准输入的数据的意思
例 将/etc/passwd和/etc/shadow同一行贴在一起
[root@centos79 ~]# paste /etc/passwd /etc/shadow | head -n 3
root:x:0:0:root:/root:/bin/bash root:$6$nrs0dBveBSd3P.Lt$pH9Lt3jvS0.yndIhsA2q.OApegOtgyGpfJUca4cQG523ldbkmNsXMDQBmIA2IQvP0piQY.17miuXQLBKp1zLe/::0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:18397:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:18397:0:99999:7:::
例2 先将/etc/group读出,然后与例1贴在一起 [tips]
[root@centos79 ~]# cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3 #-表示stdin
root:x:0:0:root:/root:/bin/bash root:$6$nrs0dBveBSd3P.Lt$pH9Lt3jvS0.yndIhsA2q.OApegOtgyGpfJUca4cQG523ldbkmNsXMDQBmIA2IQvP0piQY.17miuXQLBKp1zLe/::0:99999:7:::root:x:0:
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:18397:0:99999:7::: bin:x:1:
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:18397:0:99999:7::: daemon:x:2:
split可以将一个大文件依据文件大小或行数来划分,将大文件划分为小文件
split [-bl] file PREFIX
-b 后面可接欲划分成的文件大小,可加单位b,k,m等
-l 以行数来进行划分
PREFIX 代表前缀字符的意思,可作为划分文件的前缀文字
例1 将/etc/services划分成300k一个的文件
[root@centos79 ~]# ll -h /etc/services
-rw-r--r--. 1 root root 677K May 15 2020 /etc/services
[root@centos79 ~]# cd /tmp;split -b 300k /etc/services service
[root@centos79 tmp]# ll -h service*
-rw-r--r--. 1 root root 300K Dec 18 13:39 serviceaa
-rw-r--r--. 1 root root 300K Dec 18 13:39 serviceab
-rw-r--r--. 1 root root 77K Dec 18 13:39 serviceac #划分成的文件名根据PREFIX的值,以PREFIXaa,PREFIXab,PREFIXac等方式来命名
例2 将上面的三个小文件合成一个文件,文件名为servicesbak
[root@centos79 tmp]# cat servicea* >> servicesback
例3 使用ls -al /输出的信息中,没事行记录成一个文件
[root@centos79 tmp]# ls -al / | split -l 10 - lsroot #如果需要stdin或stdout时,但又没有文件,有的只是-时,那么这个-会被当成stdin或stdout [tips]
[root@centos79 tmp]# ll -h lsroota*
-rw-r--r--. 1 root root 477 Dec 18 13:45 lsrootaa
-rw-r--r--. 1 root root 497 Dec 18 13:45 lsrootab
-rw-r--r--. 1 root root 96 Dec 18 13:45 lsrootac
[root@centos79 tmp]# wc -l lsroota*
10 lsrootaa
10 lsrootab
2 lsrootac
22 total
很多命令并不支持管道命令,但是我们可以通过xargs来提供该命令使用标准输入。xargs可以将stdout作为stdin来读入(管道命令),并且以空格符或换行符来作为标识符,将stdin的数据分割成为参数。注意:因为是以空格符作为分割,所以如果有一些文件名或是其他意义的名词内含有空格符时,xargs可能会误判。
xargs [-0epn] command
当xargs后面没有接任何命令时,默认是以echo来进行输出
-0 如果输入的stdin含有特殊字符,例如` \ 空格 等字符时,-0可以将它还原成一般字符,这个参数可以用于特殊状态
-e 这是EOF(end of file)的意思,后面可以接一个字符,-e和字符之间不能有空格[tips],当xargs分析到这个字符时,就会停止工作
-p 在执行每个命令时,都会询问使用者
-n 后面接数字,每次command命令执行时,需要使用几个参数的意思
例1 取出/etc/passwd前3行的第一栏数据(即账号),将该数据作为id的参数,列出前三个账号的gid,uid,groups
[root@centos79 tmp]# id $(cut -d ':' -f 1 /etc/passwd | head -n 3)
id: extra operand 'bin' #虽然$(cmd)可以先执行,取出前三行的用户名,但是id这个命令仅能接收一个参数,所以会报错
Try 'id --help' for more information.
[root@centos79 tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 #因为id并不是管道命令,因此此命令执行后,前面的东西通通不见,只会执行id [tips]
[root@centos79 tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs id
id: extra operand 'bin' #依然会报错,这是因为xargs一口气将全部的stdout通通丢给id去处理,但是id每次只能接收1个参数
Try 'id --help' for more information.
[root@centos79 tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id #通过-n来处理,一次给予一个参数
uid=0(root) gid=0(root) groups=0(root)
uid=1(bin) gid=1(bin) groups=1(bin)
uid=2(daemon) gid=2(daemon) groups=2(daemon)
例2 将所有的/etc/passwd内的账号都以id查看,但是查到sync时就结束
[root@centos79 tmp]# cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id #-e和'sync'之间是连在一起的,不能有空格
uid=0(root) gid=0(root) groups=0(root)
uid=1(bin) gid=1(bin) groups=1(bin)
uid=2(daemon) gid=2(daemon) groups=2(daemon)
uid=3(adm) gid=4(adm) groups=4(adm)
uid=4(lp) gid=7(lp) groups=7(lp)
例3 找出/usr/sbin下面具有特殊权限的文件名,并使用ls -l列出详细属性
#因为ls不是管道命令,所以可以使用xargs
[root@centos79 tmp]# find /usr/sbin -perm /7000 | xargs ls -l #ls可以接受数组,所以不需要加-n选项
-rwsr-xr-x. 1 root root 69240 Mar 2 2021 /usr/sbin/grub2-set-bootflag
-rwx--s--x. 1 root lock 70568 May 11 2019 /usr/sbin/lockdev
-rwsr-xr-x. 1 root root 69432 Dec 2 2020 /usr/sbin/pam_timestamp_check
-rwsr-xr-x. 1 root root 70360 Dec 2 2020 /usr/sbin/unix_chkpwd
-rws--x--x. 1 root root 71592 May 11 2019 /usr/sbin/userhelper
#也可以使用$(cmd)来优先处理,然后将处理的结果作为ls的参数
[root@centos79 tmp]# ls -l $(find /usr/sbin -perm /7000)
-rwsr-xr-x. 1 root root 69240 Mar 2 2021 /usr/sbin/grub2-set-bootflag
-rwx--s--x. 1 root lock 70568 May 11 2019 /usr/sbin/lockdev
-rwsr-xr-x. 1 root root 69432 Dec 2 2020 /usr/sbin/pam_timestamp_check
-rwsr-xr-x. 1 root root 70360 Dec 2 2020 /usr/sbin/unix_chkpwd
-rws--x--x. 1 root root 71592 May 11 2019 /usr/sbin/userhelper
查询指定用户的UID/GID/groups
id 用户名
id后面不接用户名时查询当前登录用户的UID、GID和groups
格式化打印
printf '打印格式' 实际内容
打印格式:
\a 警告声音输出
\b 退格键
\f 清除屏幕
\n 输出新的一行
\r 回车键
\t 水平的tab键
\v 垂直的tab键
\xNN NN为两位数的数字,可以转换数字成为字符
%ns n是数字,s代表string,亦即多少个字符
%ni n是数字,i代表integer,亦即多少整数位数
%N.nf n和N都是数字,f代表floating,如果有小数位数,假设我共要十位数,但是小数点有两位,即%10.2f
%s 代表一个不固定长度的字符串
#printf.txt的内容如下
[root@centos79 ~]# cat printf.txt
Name Chinese English Math Average
Tom 80 60 92 77.33
Job 75 55 80 70.00
Lin 60 90 70 73.33
例1
[root@centos79 ~]# printf '%s\t %s\t%s\t%s\t%s\t \n' $(cat printf.txt)
Name Chinese English Math Average
Tom 80 60 92 77.33
Job 75 55 80 70.00
Lin 60 90 70 73.33
#因为printf不是管道命令,所以先使用$()将文件内容读出来再传给printf,也可以使用cat printf.txt | xargs printf '%s\t %s\t %s\t %s\t %s\t \n'
例2
[root@centos79 ~]# printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt | grep -v Name)
Tom 80 60 92 77.33
Job 75 55 80 70.00
Lin 60 90 70 73.33
#%10s代表一个长度为10个字符的字符串字段,%5i代表的是长度为5个字符的数字字段,%8.2f代表的是长度为8个字符的具有小数点的字段,其中小数点有两个字符的宽度,小数点本身占一位,即%8.2f表示00000.00。[tips]
awk可以将一行当中的内容分成数个字段来处理,默认的分隔符为空格或tab,可以使用-F ''来指定分隔符
awk '条件类型1{操作1} 条件类型2{操作2} ...' filename
#$0代表一整列数据,$1代表第一列字段,$2代表第二列字段...。$0是m行n列的矩阵、$1、$2...是m行1列的矩阵 [tips]
#awk处理流程:1.读入第一行,并将第1行的数据写入$0,$1,$2,...中;2.根据”条件类型“的限制,判断是否需要进行后面的”操作“;3.完成所有操作与条件类型;4.若还有后续的【行】的数据,则重复上面1~3的步骤,直到所有的数据都读完为止。
#awk的内置变量:NF:每一行($0)拥有的字段总数,即每一行被分成了NF段;NR:目前awk所处理的是第几行的数据;FS:目前的分隔符,默认是空格键 【tips】
#awk的逻辑运算字符:>,<,>=,<=,==,!=
例1 将登陆者的用户名和ip取出来,中间用tab分隔
[root@centos79 ~]# last -n 5
root pts/0 192.168.1.7 Thu Dec 29 23:15 still logged in
root pts/2 192.168.1.7 Thu Dec 29 20:31 - 23:00 (02:29)
root pts/1 192.168.1.7 Thu Dec 29 20:28 - 22:32 (02:03)
root pts/0 192.168.1.7 Thu Dec 29 18:43 - 22:26 (03:42)
root tty1 Thu Dec 29 18:43 still logged in
wtmp begins Tue Nov 29 17:14:07 2022
[root@centos79 ~]# last -n 5 | awk '{print $1 "\t" $3}' #因为每一行都要处理,所以不需要有"条件类型"
root 192.168.1.7
root 192.168.1.7
root 192.168.1.7
root 192.168.1.7
root Thu
wtmp Tue
例2
[root@centos79 ~]# last -n 5 | awk '{print $1 "\t lines: " NR "\t columns: " NF "\t Separator: " FS}' #单引号''内的非变量的文字部分,都需要使用双引号""来定义出来。 在awk中,NR、NF、FS等变量要用大写,且不需要有美元符号$
root lines: 1 columns: 10 Separator:
root lines: 2 columns: 10 Separator:
root lines: 3 columns: 10 Separator:
root lines: 4 columns: 10 Separator:
root lines: 5 columns: 9 Separator:
lines: 6 columns: 0 Separator:
wtmp lines: 7 columns: 7 Separator:
例3
[root@centos79 ~]# cat /etc/passwd | awk -F ':' '$3<10 {print $1 "\t" $3}' #以":"为分隔符,如果第三个字段小于10,则执行{print $1 "\t" $3}操作
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
例4
[root@centos79 ~]# cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "\t" $3}'
#{FS=":"}是操作1,条件1为空,{FS=":"}表示指定分隔符为":",相当于-F ":",与-F ":"不同的是,{FS=":"}仅能在第二行后才开始生效,可以使用BEGIN这个关键字让{FS=":"}在第一行就生效,见例5。$3<10是条件2,{print $1 "\t" $3}是操作2。【tips】
root:x:0:0:root:/root:/bin/bash #第一行没有生效
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
例5
[root@centos79 ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3<10 {print $1 "\t" $3}'
#类似BEGIN,同样有END关键字【tips】
root 0 #第一行开始生效
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
例6 awk的计算功能
[root@centos79 ~]# cat pay.txt
Name 1st 2nd 3th
Tom 23000 24000 25000
Job 21000 20000 25000
Lin 34000 35000 40000
[root@centos79 ~]# cat pay.txt | awk 'NR==1 {printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"} NR>=2 {printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$4,$2+$3+$4}'
Name 1st 2nd 3th Total
Tom 23000 24000 25000 72000.00
Job 21000 20000 25000 66000.00
Lin 34000 35000 40000 109000.00
sed可以将数据进行替换、删除、新增、选取特定行等功能
sed [-nefr] ['操作']
选项说明:
-n 使用安静模式,在一般sed的用法中,所有来自stdin的数据一般都会被列出到屏幕上,但是加上-n后,则只有经过sed特殊处理的那一行(或操作)才会被列出来
-e 直接在命令行模式上进行sed的操作编辑,-e可以省略
-f 直接将sed的操作写在一个文件内,-f filename则可以执行filename内的sed操作
-r sed的操作使用的是扩展型正则表达式的语法,默认使用基础正则表达式语法
-i 直接修改读取的文件内容,而不是由屏幕输出
操作说明:
'[n1[,n2]]function' #要使用单引号''括住
n1,n2 不见得会存在,一般代表【选择进行操作的行数】,举例来说,如果我的操作是需要在10到20行之间进行的,则【10,20[function]】
function:
a 新增,a的后面可以接字符,而这些字符会在新的一行出现(目前的下一行)
c 替换,c的后面可以接字符,这些字符可以替换n1,n2之间的内容
s 替换,可以直接进行替换的工作,通常这个s的操作可以搭配正则表达式,例如将1,20行内的old用new来替换:sed '1,20s/old/new/g',将所有的old用new来替换:sed 's/old/new/g'。其中g代表全局,全局查找。[tips]
d 删除,因为是删除,所以d后面通常不接任何东西
i 插入,i的后面可以接字符,而这些字符会出现在新的一行(目前的上一行)
p 打印,亦即将某个选择的数据打印出来,通常p会与参数sed -n一起运行
例1 将/etc/passwd的内容列出,同时将第2-5行删除
[root@centos79 ~]# cat -n /etc/passwd | sed '2,5d'
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
...
例2 将/etc/passwd的内容列出,同时将第2行删除
[root@centos79 ~]# cat -n /etc/passwd | sed '2d'
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
例3 将/etc/passwd的内容列出,同时将第2行到最后一行删除[tips]
[root@centos79 ~]# cat -n /etc/passwd | sed '2,$d'
1 root:x:0:0:root:/root:/bin/bash
例4 将/etc/passwd的内容列出,同时在第二行下面增加字符串:drink tea
[root@centos79 ~]# cat -n /etc/passwd | sed '2a drink tea'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
drink tea
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
例5 将/etc/passwd的内容列出,同时在第二行上面增加两行字符串:drink tea和drink milk
[root@centos79 ~]# cat -n /etc/passwd | sed '2i drink tea\
> drink milk' #可以同时增加好几行,每行之间必须要以反斜杠\来进行新行的增加
1 root:x:0:0:root:/root:/bin/bash
drink tea
drink milk
2 bin:x:1:1:bin:/bin:/sbin/nologin
...
例6 将/etc/passwd的内容列出,同时将第2-5行的内容替换成为字符串ABC
[root@centos79 ~]# cat -n /etc/passwd | sed '2,5c ABC'
1 root:x:0:0:root:/root:/bin/bash
ABC
6 sync:x:5:0:sync:/sbin:/bin/sync
例7 仅取出/etc/passwd的第2-4行
[root@centos79 ~]# cat -n /etc/passwd | sed -n '2,4p' #需要加上-n,如果不加-n则会将全部内容显示到终端
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
例8 将./regular_express.txt的内容列出,同时将第2到6行中的c用Z来替换
[root@centos79 ~]# cat -n regular_express.txt
1 a
2 b
3 c
4 a
5 b
6 c
7 c
8 b
9 a
10
[root@centos79 ~]# cat -n regular_express.txt | sed '2,6s/c/Z/g'
1 a
2 b
3 Z
4 a
5 b
6 Z
7 c
8 b
9 a
10
例8 将./regular_express.txt的内容列出,同时将全文中的a删除
[root@centos79 ~]# cat -n regular_express.txt | sed 's/a//g'
1
2 b
3 c
4
5 b
6 c
7 c
8 b
9
10
例9 将./regular_express.txt的内容列出,同时将含有a的所有行删除 [tips]
[root@centos79 ~]# cat -n regular_express.txt
1 a
2 b
3 c
4 ab
5 b
6 c
7 c
8 b
9 a
10
[root@centos79 ~]# cat -n regular_express.txt | sed '/a/d' #d不一定非要和行号配合使用[tips]
2 b
3 c
5 b
6 c
7 c
8 b
10
例9 将./regular_express.txt的内容列出,同时将所有空白行删除 [tips]
[root@centos79 ~]# cat regular_express.txt | sed '/^$/d' #^$表示空白行
a
b
c
ab
b
c
c
b
a
例11 获取ip [tips]
[root@centos79 ~]# ifconfig ens160
ens160: flags=4163 mtu 1500
inet 192.168.1.9 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 2409:8a1e:1ae3:f040:20c:29ff:fe7f:d6c8 prefixlen 64 scopeid 0x0
inet6 2409:8a1e:1ae4:8410:20c:29ff:fe7f:d6c8 prefixlen 64 scopeid 0x0
inet6 fe80::20c:29ff:fe7f:d6c8 prefixlen 64 scopeid 0x20
inet6 2409:8a1e:1aec:a2a0:20c:29ff:fe7f:d6c8 prefixlen 64 scopeid 0x0
ether 00:0c:29:7f:d6:c8 txqueuelen 1000 (Ethernet)
RX packets 502746 bytes 125026432 (119.2 MiB)
RX errors 0 dropped 19 overruns 0 frame 0
TX packets 112444 bytes 81816583 (78.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 54 memory 0x3fa00000-3fa20000
[root@centos79 ~]# ifconfig ens160 | grep ' inet ' | sed 's/.*inet //' | sed 's/ *netmask.*//'
192.168.1.9
例12 将./regular_express.txt内每一行结尾若为.则换成!(直接修改原文件)
[root@centos79 ~]# sed -i 's/\.$/\!/g' ./gular_express.txt
tips:
sed 后面接单引号和三个斜杠'///'
awk 后面接单引号和大括号'{}'
diff比对两个相关文件之间的差异,并且以行为单位进行比对,一般用在ASCII纯文本文件的比对上,diff通常是用在同一个文件(或软件)的新旧版本差异上。
diff [-bBi] from-file to-file
from-file 文件名,作为原始比对文件的文件名
to-file 文件名,作为目标比对文件的文件名
-b 忽略一行中,仅有多个空白的差异,例如”about me“与”about me“视为相同
-B 忽略空白行的差异
-i 忽略大小写的差异
例1 比对两个文件之间的差异
[root@centos79 ~]# cat -n t1.txt
1 Job
2 Lin
3 Tom
4 Jhon
5 Ken
[root@centos79 ~]# cat -n t2.txt
1 Lair
2 Lin
3 Jhon
4 Ken
5 Fan
[root@centos79 ~]# diff t1.txt t2.txt
1c1 #以右边文件(t2.txt)的第一行为基准,左边文件(t1.txt)的第一行内容被Job替换(c)了
< Job #左边文件的第一行内容是Job
---
> Lair #右边文件的第一行内容是Lair
3d2 #以右边文件的第2行为基准,左边文件的第3行被删除(d)了
< Tom #左边文件第三行的内容为Tom
5a5 #以右边文件的第5行为基准,左边文件的第5行增加(a)了内容
> Fan #右边文件的第5行内容为Fan
例2 比对两个目录间的差异
[root@centos79 ~]# ll d1 d2
d1:
total 0
drwxr-xr-x. 2 root root 6 Dec 30 05:37 d11
-rw-r--r--. 1 root root 0 Dec 30 05:36 t1
-rw-r--r--. 1 root root 0 Dec 30 05:37 t2
d2:
total 0
-rw-r--r--. 1 root root 0 Dec 30 05:36 t1
[root@centos79 ~]# diff d1 d2
Only in d1: d11
Only in d1: t2
cmp用于比对两个文件,主要利用字节单位去比对,因此可以比对二进制文件
cmp [-l] file1 file2
-l 将所有不同点的字节处都列出来,默认仅会输出第一个发现的不同点
[root@centos79 ~]# cmp t1.txt t2.txt
t1.txt t2.txt differ: char 1, line 1 #第一行的第一个字符不相同
Linux默认会启动7个终端登录环境的进程,所以我们会有6个终端界面,使用Alt+F1...F7可以切换不同的终端界面,每个终端界面的登陆者可以不同。当我们的主机不能通过ssh登录时(没有网络或ssh限制登录时),而碰巧我们当前的终端中某个进程卡住,导致我们终端界面卡住时,我们可以使用Alt+F1...F7来切换到不同的终端界面,使用ps -aux找到刚刚卡住的进程,然后使用kill来终止卡住的进程即可,而不必重启主机。[tips]
knowledge:tty1和pts/0的区别
tty表示本地登录终端,即通过console登录的终端界面
pts/0表示远程(ssh)登录的终端
&表示bash后台执行,也就是说执行这一个命令之后,在这一个终端界面仍然可以做其他任务,但是该命令回显的信息仍然会打印在当前终端界面,并且当这个命令执行完毕之后,系统将会在终端界面显示完成的消息
[root@centos79 ~]# tar -zpcf /tmp/etc.tar.gz /etc &
[1] 3176 [1]表示任务号码为1 3176表示这个任务在系统中的PID为3176
tar: Removing leading `/' from member names #此处输出的信息是tar -zpcf /tmp/etc.tar.gz /etc 执行过程中的输出,因为没有使用数据流重定向,所以会出现在当前终端
[1]+ Done tar -zpcf /tmp/etc.tar.gz /etc #会在命令行中输入命令的时候突然出现,表示任务号码为1的任务在后台执行完毕了
[root@centos79 ~]# tar -zpcvf /tmp/etc.tar.gz /etc > /tmp/log.txt 2>&1 &
[1] 3185 #正确用法,将输出的结果全部重定向到/tmp/log.txt,避免在当前终端界面打印
ctrl+z表示将当前的任务先暂停,然后丢到bash后台中去
[root@centos79 ~]# vim ~/.bashrc
#在vim界面按在ctrl+z
[1]+ Stopped vim ~/.bashrc #[1]+中的+表示最近一个被丢到后台的任务,且是目前后台默认会被使用的那个任务,Stopped表示目前这个任务的状态-暂停状态
[root@centos79 ~]# #顺利获取了前台的操控权
[root@centos79 ~]# find / -print
...
/sys/devices/platform/40000000.pcie/pci0000:00/0000:00:11.0/0000:01:03.0/ata20/link20/ata_link/link20/power/autosuspend_delay_ms
/sys/devices/platform/40000000.pcie/pc^Z #按下ctrl+z
[2]+ Stopped find / -print
[root@centos79 ~]#
jobs [-lrs]
不接任何选项和参数 列出当前bash下的后台任务号码,命令串
-l 除了列出任务号码和命令串外,同时列出pid
-r 仅列出正在后台run的任务
-s 仅列出正在后台中暂停的任务
[root@centos79 ~]# jobs -l
[1]- 3204 Stopped vim ~/.bashrc #-表示最近第二个被放置到后台中的任务号码,第三个及以后的任务就不会有+和-符号的存在了
[2]+ 3213 Stopped find / -print
fg %jobnumber %jobnumber jobnumber为任务号码,%可有可无,表示将后台中的任务拿到前台,并将该任务启动
fg - 将有-的那个任务拿到前台来执行并启动
fg 直接执行fg表示会将带有+的那个任务拿到前台来执行并启动
用法同fg,bg表示将后台暂停的任务在后台启动
[root@centos79 ~]# jobs
[1]- Stopped vim ~/.bashrc
[2]+ Stopped find / -perm /7000 > /tmp/text.txt 2>&1
[root@centos79 ~]# bg 2
[2]+ find / -perm /7000 > /tmp/text.txt 2>&1 & #在最后多了个&符号,代表该任务被启动到后台了
kill表示给指定的任务发送一个信号(signal),这个信号可以将该任务直接删除或重新启动等
kill -l 列出目前kill能够使用的信号signal有哪些
[root@centos79 ~]# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
#代号:1 名称:SIGHUP 含义:启动被终止的进程,可让该pid重进读取自己的配置文件,类似于重新启动(systemctl restart)
#代号:2 名称:SIGINT 含义:相当于用键盘输入ctrl-c来中断一个进程的运行 [tips]
#代号:9 名称:SIGKILL 含义:强制中断一个进程的执行,如果该进程执行到一半,那么尚未完成的部分可能会产生【半成品】,类似vim会有.filename.swp保留下来 [tips]
#代号:15 名称:SIGTERM 含义:以正常的方式结束进程来终止该进程。由于是正常的终止,所以后续的操作会将它完成。不过,如果该进程已经发生问题,就无法使用正常的方法终止时,输入这个信号也是没有用的
#代号:19 名称:SIGTOP 含义:相当于用键盘输入ctrl-z来暂停一个进程的运行 [tips]
kill -signal %jobnumber #%不能省略,%省略时表示输入的是pid
signal 代表给与后面接的那个任务什么样的信号(指示),使用man 7 signal可以查看所有的信号说明
常用signal:
-1 重新读取一次参数的配置文件(类似reload)
-2 代表由键盘输入ctrl+c同样的操作
-9 立刻强制删除一个任务
-15 以正常的进程方式终止一项任务,kill的默认信号为15
[root@centos79 ~]# jobs
[1]- Stopped vim ~/.bashrc
[2]+ Stopped find / -perm /7000 > /tmp/text.txt 2>&1
[root@centos79 ~]# kill -9 %2 #kill -SIGKILL %2等价于kill -9 %2
[2]+ Stopped find / -perm /7000 > /tmp/text.txt 2>&1
[root@centos79 ~]# jobs
[1]- Stopped vim ~/.bashrc
[2]+ Killed find / -perm /7000 > /tmp/text.txt 2>&1
kill -signal pid #给与指定pid的进程一个信号
killall后面可以接执行命令的名称,常用于操作某个清楚名称的服务进程 [tips]
killall -signal [-iIe] [command name]
i interactive,即互动的意思,若要删除时,会出现提示字符给使用者
e exact,表示后面接的command name要一致,但是完整command name不能超过15个字符
I 命令名称忽略大小写
例1 给予rsyslogd这个命令启动的PID一个SIGHUP
[root@centos79 ~]# ps -ef | grep -v grep | grep rsyslogd
root 1178 1 0 Dec28 ? 00:00:10 /usr/sbin/rsyslogd -n #command name为/usr/sbin/rsyslogd -n
[root@centos79 ~]# killall -1 -i rsyslogd
Signal rsyslogd(1178) ? (y/N)
例2 杀死所有的bash,包括当前连接的bash
[root@centos79 ~]# killall -9 bash
&和ctrl+z可以将任务后台运行,这里说的后台运行指的是当前bash的后台,而不是系统的后台。[tips]
bash后台:bash后台与终端有关,如果你是以远程连接的方式连接到linux主机,并且将任务以&的方式放到后台中,在该任务尚未结束的情况下你退出登录了,那么该任务将会中断,而不会继续执行。
系统后台:系统后台与终端无关,用户退出登录时任务仍然会继续执行。
nohup和at定时任务可以将任务放到系统后台运行
nohup [命令与参数] #在终端前台运行命令
nohup [命令与参数] & #在终端后台运行命令
例1
[root@centos79 ~]# nohup ./sleep500.sh &
[2] 3307
[root@centos79 ~]# nohup: ignoring input and appending output to 'nohup.out' #将任务的输出写到~/nohup.out中
例2 #将stdout和stderr输出的指定的文件/root/nohup1.out中
[root@centos79 ~]# nohup ./sleep500.sh >> /root/nohup1.out 2>&1 &
[5] 3637
ps会将某个时间点的进程运行情况截取下来,相当于静态显示进程
#列出系统所有运行的进程:1.ps aux 2.ps -ef 3.ps -lA
#差别如下:
[root@centos79 ~]# ps aux | grep -E "sleep|TTY"
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 3527 0.0 0.0 3500 1040 pts/0 S 00:56 0:00 /bin/bash ./sleep500.sh
root 3528 0.0 0.0 1964 540 pts/0 S 00:56 0:00 sleep 500s
root 3549 0.0 0.0 2828 864 pts/0 S+ 00:58 0:00 grep --color=auto -E sleep|TTY
#USER表示这个进程所属用户账号
#PID表示此进程的PID
#%CPU表示CPU使用率
#%MEM表示该进程的物理内存使用率
#VSZ表示该进程使用的虚拟内存量,单位为KB
#RSS表示该进程占用的固定的内存量,单位为KB
#TTY表示该进程是在哪个终端上面运行,若与终端无关则显示?。tty1-tty6是本机上面的登录进程(console),pts/n表示远程登录的动态终端接口名称 [tips]
#STAT表示这个进程的状态(STAT),主要状态有R:Running;S:Sleep,睡眠状态,可以被唤醒(signal);D:不可被唤醒的睡眠状态,通常这个进程可能在等待I/O的情况(打印);T:Stop,停止状态,可能是在任务控制(后台暂停)或跟踪(traced)状态;Z:Zombie,僵尸状态,该进程已经终止但却无法被删除至内存外
#START表示该进程被触发启动的时间
#TIME表示使用CPU时间,即此实际花费CPU运行的时间
#COMMAND表示造成此进程的触发进程的命令是什么
[root@centos79 ~]# ps -ef | grep -E "sleep|TTY"
UID PID PPID C STIME TTY TIME CMD
root 3527 3427 0 00:56 pts/0 00:00:00 /bin/bash ./sleep500.sh
root 3528 3527 0 00:56 pts/0 00:00:00 sleep 500s
root 3551 3427 0 00:58 pts/0 00:00:00 grep --color=auto -E sleep|TTY
#UID表示该进程的拥有者
#PID表示此进程的PID
#PPID表示此进程的父进程的PID
#C表示CPU使用率,单位为百分比
#STIME表示START TIME,即该进程被触发启动的时间
#TIME表示使用CPU时间,即此实际花费CPU运行的时间
[root@centos79 ~]# ps -lA | grep -E "sleep|TTY"
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 0 3527 3427 0 80 0 - 875 do_wai pts/0 00:00:00 sleep500.sh
0 S 0 3528 3527 0 80 0 - 491 hrtime pts/0 00:00:00 sleep
#查看当前bash下的进程,最上层的父进程是当前的bash,而不是systemd
ps -lf
[root@centos79 ~]# ps -lf
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
0 S root 3427 3426 0 80 0 - 4399 do_wai 00:31 pts/0 00:00:00 -bash
0 S root 3575 3427 0 80 0 - 875 do_wai 01:09 pts/0 00:00:00 /bin/bash ./sleep500.sh
0 S root 3576 3575 0 80 0 - 491 hrtime 01:09 pts/0 00:00:00 sleep 500s
4 R root 3581 3427 0 80 0 - 4445 - 01:09 pts/0 00:00:00 ps -lf
#F表示这个进程标识(process flags),说明这个进程的权限,常见号码有:4表示此进程的权限为root,1表示此进程仅执行复制(fork),而没有实际执行(exec)
#S表示这个进程的状态(STAT),主要状态有R:Running;S:Sleep,睡眠状态,可以被唤醒(signal);D:不可被唤醒的睡眠状态,通常这个进程可能在等待I/O的情况(打印);T:Stop,停止状态,可能是在任务控制(后台暂停)或跟踪(traced)状态;Z:Zombie,僵尸状态,该进程已经终止但却无法被删除至内存外
#UID表示该进程的拥有者
#PID表示此进程的PID
#PPID表示此进程的父进程的PID
#C表示CPU使用率,单位为百分比
#PRI/NI表示Priority/Nice的缩写,表示此进程被CPU所执行的优先级,数值越小代表该进程越快被CPU执行
#ADDR/SZ/WCHAN:都与内存有关,ADDR是kernel function,指出该进程在内存的哪个部分,如果是个running的进程,一般会显示-,SZ代表此进程用掉多少内存,WCHAN表示目前进程是否在运行,-表示正在运行中
#TTY表示登录者的终端位置,若为远程登录则使用动态终端接口名称pts/n
#TIME表示使用CPU时间,即此实际花费CPU运行的时间
#CMD表示造成此进程的触发进程的命令是什么
#列出类似进程树的进程显示
ps axjf
pstree根据各进程的相关性,以进程树的形式列出所有进程,
pstree [-A|U] [-up]
A 各进程树之间的连接以ASCII字符来连接
U 各进程树之间的连接以Unicode的字符来连接
p 列出每个进程的pid
u 列出每个进程的所属账号名称
[root@centos79 ~]# pstree -A
systemd-+-ModemManager---2*[{ModemManager}]
|-NetworkManager---2*[{NetworkManager}] #2*表示子进程的数量
|-agetty
|-alsactl
|-atd
|-auditd-+-sedispatch
...
[root@centos79 ~]# pstree -puA
systemd(1)-+-ModemManager(907)-+-{ModemManager}(914) #所有进程都依附在systemd这个进行下面,systemd进程的pid为1
| `-{ModemManager}(918)
|-NetworkManager(945)-+-{NetworkManager}(947)
| `-{NetworkManager}(948)
|-agetty(3152)
|-alsactl(899)
|-atd(1190)
|-auditd(874)-+-sedispatch(876)
| |-{auditd}(875) #()内的即PID和该进程的owner,若该进程的拥有者与父进程相同,则仅列出pid
相对于ps是取一个时间点的进程状态,top则可以持续检测进程运行的状态,动态显示进程,相当于windows中的任务管理器
top -[dbnp]
d 后面接数字,指定top界面刷新的时间(秒),默认为5秒刷新一下
b 以批量的方式执行top,通常会搭配数据流重定向来将批量的结果输出为文件
n 与-b搭配,表示连续执行几次top命令
p 后面接pid,查看指定pid的进程
在top执行过程中常用的按键:
? 显示在top当中可以输入的命令
P 以CPU的使用排序显示(默认)
M 以内存的使用排序显示
N 以PID来排序显示
T 以该进程使用的CPU时间积累(TIME+)排序
k 给予某个PID一个信号signal
r 给予某个PID重新制定一个nice值
q 退出top
[root@centos79 ~]# top -d 2
top - 03:31:13 up 1 day, 8:58, 3 users, load average: 0.00, 0.00, 0.00
Tasks: 218 total, 1 running, 217 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3397.5 total, 2489.9 free, 324.0 used, 583.7 buff/cache
MiB Swap: 1024.0 total, 1024.0 free, 0.0 used. 3022.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3761 root 20 0 18700 4196 3348 R 0.7 0.1 0:00.10 top
3733 root 20 0 46868 5116 3872 S 0.3 0.1 0:00.01 sshd
1 root 20 0 108004 13548 8672 S 0.0 0.4 0:02.36 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.09 kthreadd
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_gp
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H-events_highpri
#第一行:
#目前的时间:即03:31:13
#开机到目前为止所经过的时间:up 1 day, 8:58,即已经运行了1天8小时58分
#已经登录系统的用户人数:即3 users
#系统在1、5、15分钟的任务队列的平均长度,1分钟前到现在任务队列的平均长度为0.00,5分钟前到现在任务队列...
#第二行:显示的是目前进程的总量与个别进程在什么状态(Running、sleeping、stopped、zombie)
#第三行:显示的是CPU的整体负载,如果linux主机有多个cpu,则可以按1来切换不同cpu的负载 [tips]
#us:用户空间占用cpu百分比
#sy:内核空间占用cpu百分比
#ni:用户进程空间内改变过优先级的进程占用cpu百分比
#id:空闲cpu百分比,反映系统cpu的空闲程度,数值越大表示越空闲
#wa:I/O wait,通常你的系统变慢都是I/O产生的问题比较大,因此要注意wa耗用CPU的资源
#hi:cpu处理硬件中断的时间
#si:cpu处理软件中断的时间
#st:用于有虚拟cpu的情况,用来指示被虚拟机偷掉的cpu时间
#第四行,第五行:表示目前物理内存(member)与虚拟内存(swap)的使用情况,默认显示单位为MB
#第六行:这个是当在top进程当中输入命令时,显示状态的地方
#第六行以下:每个进程使用的资源情况
#PID
#USER:该进程所属的用户
#PR:priority,进程的优先执行顺序,越小则越早被执行
#NI:nice,与priority有关,越小则越早被执行
#%CPU:该进程的CPU使用率
#%MEM:该进程的内存使用率
#TIME+:该进程CPU使用时间的累加
#VIRT:进程使用的虚拟内存总量,单位kb。
#RES:进程使用的、未被换出的物理内存大小,单位kb。
#SHR:共享内存大小,单位kb
例1,将top的信息执行两次,然后将结果输出到/tmp/top.txt
[root@centos79 ~]# top -b -n 2 > /tmp/top.txt
例2,如果你想要查看的进程cpu和内存使用率都很低,无法在第一行显示时,该怎么办?可以查看单一的进程。如:查看当前bash的进程状态
[root@centos79 ~]# echo $$ #打印当前bash的pid
3734
[root@centos79 ~]# top -d 2 -p 3734
top - 04:22:43 up 1 day, 9:49, 3 users, load average: 0.00, 0.00, 0.00
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3397.5 total, 2489.6 free, 324.2 used, 583.7 buff/cache
MiB Swap: 1024.0 total, 1024.0 free, 0.0 used. 3022.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3734 root 20 0 17336 4928 3036 S 0.0 0.1 0:00.06 bash
[root@centos79 ~]# top -d 2 -p 3734 -p 3426 #查看两个进程
top - 10:49:45 up 1 day, 9:53, 3 users, load average: 0.00, 0.00, 0.00
Tasks: 2 total, 0 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3397.5 total, 2489.0 free, 324.4 used, 584.1 buff/cache
MiB Swap: 1024.0 total, 1024.0 free, 0.0 used. 3021.8 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3734 root 20 0 17336 4928 3036 S 0.0 0.1 0:00.09 bash
3426 root 20 0 46868 5676 4408 S 0.0 0.2 0:00.76 sshd
例3,在top中修改指定pid的nice值 [tips]
[root@centos79 ~]# top -d 2
top - 10:54:48 up 1 day, 9:58, 3 users, load average: 0.03, 0.01, 0.00
Tasks: 218 total, 1 running, 217 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.5 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 3397.5 total, 2489.3 free, 324.1 used, 584.1 buff/cache
MiB Swap: 1024.0 total, 1024.0 free, 0.0 used. 3022.1 avail Mem
PID to renice [default pid = 3733] 3810 #在top进程中按下r键,会出现提示,输入要修改的pid,本次修改3810,按回车,然后会提示输入新的nice值(Renice PID 3810 to value),输入新的值后按回车
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3733 root 20 0 46868 5116 3872 S 0.5 0.1 0:00.37 sshd
3810 root 20 0 18700 4200 3356 R 0.5 0.1 0:00.76 top
1 root 20 0 108004 13548 8672 S 0.0 0.4 0:02.41 systemd
例4,在top进程中杀死指定进程,如:杀死top进程 [tips]
[root@centos79 ~]# top
top - 11:04:25 up 1 day, 10:08, 3 users, load average: 0.00, 0.00, 0.00
Tasks: 218 total, 1 running, 216 sleeping, 1 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3397.5 total, 2488.6 free, 324.9 used, 584.1 buff/cache
MiB Swap: 1024.0 total, 1024.0 free, 0.0 used. 3021.3 avail Mem
PID to signal/kill [default pid = 3844] 3844 #按k键后提示:输入想要给予信号/杀死的pid,输入top进程的pid:3844,然后回车,提示:Send pid 3844 signal [15/sigterm],然后输入15或sigterm来正常结束top进程,或输入9/sigkill来强制结束top进程
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3844 root 20 0 18700 4176 3324 R 0.3 0.1 0:00.04 top
1 root 20 0 108004 13548 8672 S 0.0 0.4 0:02.43 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.10 kthreadd
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp
查看内存使用情况
free [-bkmghtsc]
b 显示的单位是Bytes
k 显示的单位是KBytes(默认)
m 显示的单位是MBytes
g 显示的单位是GBytes
h 系统指定合适的单位
t 在最终的输出结果,显示物理内存与swap的总量
s 后面接数字(单位:秒),可以让系统不断地刷新数据,类似top -d
c 后面接数字(单位:次),与-s同时使用,让free列出几次的意思,类似top -n
[root@centos79 ~]# free -m
total used free shared buff/cache available
Mem: 3397 325 2491 9 580 3020
Swap: 1023 0 1023
#Mem那行显示的是物理内存
#Swap那行显示的是交换内存(虚拟内存)
#toal是总量;used是已经被使用的量;free是剩余可用的量;shared、buff/cache则是用来作为缓冲及缓存的(系统会将空余的内存用来做缓冲及缓存,从而高效的用光内存,目的是让系统的读写性能加速),在系统比较忙碌时,shared、buff/cache可以被释放而继续利用[tips];所以available约等于free+shared+buff/cache,available表示可用。
knowledge:
linux系统为了提高系统性能,会将最常使用的或最近使用到的文件数据缓存(cache)下来,这样未来系统要使用该文件时,就可以直接从内存中查找取出,而不需要重新读取硬盘,速度上面就加快了很多,因为,物理内存被用光是正常的。
查看系统与内核相关的信息
uname [-asrmpi]
a 所有系统相关的信息,包括下面的数据都会被列出来
s 系统内核名称#Linux
r 内核的版本#5.11.12-300.el8.aarch64
m 本系统的硬件架构,例如i686或x86-64等#aarch64
p cpu的类型,与-m类似,只是显示的是cpu的类型#aarch64
i 硬件的平台#aarch64
[root@centos82 ~]# uname -a
Linux centos82 5.11.12-300.el8.aarch64 #1 SMP Fri Jul 30 12:03:15 CST 2021 aarch64 aarch64 aarch64 GNU/Linux
#主机使用的内核名称是Linux
#主机名是centos82
#内核版本是5.11.12-300.el8.aarch64
#该内核版本建立的日期是2021年1月30日
#适用于aarch64及以上等级的硬件架构平台
查看系统启动时间与任务负载,显示的结果同top命令的第一行
[root@centos79 ~]# uptime
13:02:45 up 1 day, 12:06, 3 users, load average: 0.00, 0.00, 0.00
#目前的时间:即13:02:45
#开机到目前为止所经过的时间:up 1 day, 12:06,即已经运行了1天12小时6分
#已经登录系统的用户人数:即3 users
#系统在1、5、15分钟的任务队列的平均长度,1分钟前到现在任务队列的平均长度为0.00,5分钟前到现在任务队列...
分析内核产生的信息
系统在启动的时候,内核会去检测系统的硬件,你的某些硬件到底有没有被识别,就与这个时候的检测有关,但是这些检测的过程不是没有显示在屏幕上,就是在屏幕上一闪而过,此时可以通过dmesg命令将检测结果打印到屏幕上。
检测系统资源(CPU、内存、磁盘IO等)状态变化
vmstat [-afsSdp] [延迟 [总计检测次数]]
-a 使用inactive\active(活动与否)替换buffer/cache的内存输出信息
-f 开机到目前为止,系统复制(fork)的进程数
-s 将一些事件(启动到目前为止)导致的内存变化情况说明
-S 后面接单位,让显示的数据有单位,例如K、M、G代替Bytes的
-d 列出磁盘的读写总量统计表
-p 后面接分区,可显示该分区的读写总量统计表
[root@centos79 ~]# vmstat 2 3 #共检测3次,每次的间隔为2秒
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 2551504 3248 591648 0 0 1 1 14 21 0 0 100 0 0
0 0 0 2551504 3248 591648 0 0 0 0 26 38 0 0 100 0 0
0 0 0 2551504 3248 591648 0 0 0 0 27 35 0 0 100 0 0
#进程字段(procs):r:等待运行中的进程数量,b:不可被唤醒的进程数量。这两个项目越多,代表系统越忙碌[tips]
#内存字段(memory):swpd:虚拟内存被使用的容量,free:未被使用的内存容量,buff:用于缓冲存储器的内存容量,cache:用于高速缓存的内存容量
#内存交换分区(swap):si:从磁盘中将进程取出的容量,so:由于内存不足而将没用到的进程写入到磁盘的swap的容量。如果si和so的数值太大,表示内存中的数据常常在磁盘与内存之间传输,系统的性能很差[tips]
#磁盘读写(I/O):bi:由磁盘读入的区块数量,bo:写入到磁盘中的区块数量。这部分的值越高,代表系统的I/O越忙碌,系统越慢。[tips]
#系统(system):in:每秒被中断的进程次数,cs:每秒执行的事件切换次数。这两数值越大,代表系统与外部设备的沟通越频繁,这些外部设备包括磁盘、网卡等[tips]
#CPU:us:非内核层的cpu使用状态,sy:内核层的cpu使用状态,id:闲置的状态,wa:等待I/O所耗费的cpu状态,st:用于有虚拟cpu的情况,用来指示被虚拟机用掉的cpu状态
netstat用于追踪网络或socket文件,常用在网络监控方面
netstat -[atunlp]
a 将目前系统上所有的连接、监听、socket信息都列出来
t 列出tcp网络封包的信息
u 列出udp网络封包的信息
n 不以进程的服务名称,以端口号来显示。默认情况下netstat命令会尝试解析并显示主机的主机名。
l 列出目前正在网络监听(listen)的服务
p 列出该网络服务的进程PID
r 显示本机的路由表
[root@centos79 ~]# netstat -an
Active Internet connections (servers and established) #与网络有关的部分,服务和已建立的连接
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 172 192.168.1.9:22 192.168.1.7:53079 ESTABLISHED
tcp 0 0 192.168.1.9:22 192.168.1.7:52534 ESTABLISHED
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 ::1:631 :::* LISTEN
udp 0 0 127.0.0.1:323 0.0.0.0:*
...
#Proto:网络的封包协议,主要分为TCP与UDP封包
#Recv-Q:非由用户进程连接到此socket的复制的总Bytes数
#Send-Q:非由远程主机传送过来的acknowledged总Bytes数
#Local Address:本地端的ip:port情况
#Foreign Address:远程主机的IP:port情况
#State:连接状态,主要有建立(ESTABLISED)及监听(LISTEN)
#tcp 0 0 192.168.1.9:22 192.168.1.7:52534 ESTABLISHED表示通过TCP封包的连接,远程的192.168.1.7:52534连接到本地端的192.168.1.9:22,这条连接状态是建立(ESTABLISED)的状态。【tips】
Active UNIX domain sockets (servers and established) #与本机进程相关的部分(非网络)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] DGRAM 84130 /run/user/0/systemd/notify
unix 2 [ ACC ] STREAM LISTENING 84133 /run/user/0/systemd/private
unix 2 [ ACC ] STREAM LISTENING 84140 /run/user/0/bus
unix 2 [ ACC ] STREAM LISTENING 84141 /run/user/0/pipewire-0
...
#除了网络上的连接外,linux系统上面的进程还可以接受不同进程所发送来的信息,那就是linux上面的socket文件。socket文件可以沟通不同两个进程之间的信息,因此进程可以获取对方传送过来的数据。
#Proto:一般是unix
#RefCnt:连接到此socket的进程数量
#Flags:连接的标识
#Type:socket存取的类型。主要有确认连接的STREAM与不需要确认的DGRAM两种
#State:若为connected则表示多个进程之间已经建立连接
#Path:连接到此socket的相关进程的路径,或是相关数据输出的路径
Active Bluetooth connections (servers and established) #与蓝牙相关的部分
Proto Destination Source State PSM DCID SCID IMTU OMTU Security
l2cap a0:78:17:68:b0:60 * LISTEN 27 0x0000 0x0000 672 0 MEDIUM
l2cap a0:78:17:68:b0:60 * LISTEN 23 0x0000 0x0000 672 0 MEDIUM
...
例 找出目前系统上已在监听的网络连接及其PID
[root@centos79 ~]# netstat -tulnp
Active Internet connections (only servers) #仅服务
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 952/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 956/cupsd
tcp6 0 0 :::22 :::* LISTEN 952/sshd
tcp6 0 0 ::1:631 :::* LISTEN 956/cupsd
udp 0 0 127.0.0.1:323 0.0.0.0:* 911/chronyd
udp 0 0 0.0.0.0:5353 0.0.0.0:* 901/avahi-daemon: r
udp 0 0 0.0.0.0:58930 0.0.0.0:* 901/avahi-daemon: r
udp6 0 0 :::34810 :::* 901/avahi-daemon: r
udp6 0 0 ::1:323 :::* 911/chronyd
udp6 0 0 fe80::20c:29ff:fe7f:546 :::* 4067/NetworkManager
udp6 0 0 :::5353 :::* 901/avahi-daemon: r
例 查看使用22端口的服务 【tips】
[root@centos79 ~]# netstat -an | grep :22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
#0 0.0.0.0:22表示监听所有本地ip(ipv4)的22端口,0.0.0.0:*表示外部任意的ip(ipv4)的任意端口都可以与本地0 0.0.0.0:22建立连接
tcp 0 0 192.168.1.9:22 192.168.1.7:53079 ESTABLISHED
tcp6 0 0 :::22 :::* LISTEN
#表示监听所有本地ip(ipv6)的22端口
例 查看本机的路由表
[root@centos79 ~]# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 ens160
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 ens160
借由文件或文件系统找出正在使用该文件的进程,可以使用fuser查看某个进程在启动过程中使用了多少文件,当删除文件时提示文件正在被使用,也可以使用fuser查看是哪个进程在使用此文件[tips]
fuser [-umv] [-k [-i] [-signal]] file/dir
u 除了进程的PID之外,同时列出该进程的拥有者
m 后面接的那个文件名会主动地上提到该文件系统的最顶端,常用在umount失败时[tips]
v 可以列出每个文件与进程还有命令的完整相关性
k 找出使用该文件、目录的PID,并试图以SIGKILL这个信号给与该PID
i 必须与-k配合,在删除PID之前会询问使用者的意愿
signal 例如-1、-15等,默认是SIGKILL(-9)
例 找出哪些进程在使用当前目录
[root@centos79 ~]# fuser -uv .
USER PID ACCESS COMMAND
/root: root 3968 ..c.. (root)dbus-daemon
root 3971 ..c.. (root)gvfsd
root 3976 ..c.. (root)gvfsd-fuse
root 4436 ..c.. (root)bash #因为当前的工作目录是/root,所以当前的bash在使用/root
[root@centos79 ~]# echo $$
4436
[root@centos79 /]# fuser -uv /root #切换工作目录后,当前bash不再使用/root目录
USER PID ACCESS COMMAND
/root: root 3968 ..c.. (root)dbus-daemon
root 3971 ..c.. (root)gvfsd
root 3976 ..c.. (root)gvfsd-fuse
例 找出所有使用/home这个文件系统的进程
[root@centos79 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.7G 0 1.7G 0% /dev
tmpfs 1.7G 0 1.7G 0% /dev/shm
tmpfs 1.7G 9.1M 1.7G 1% /run
tmpfs 1.7G 0 1.7G 0% /sys/fs/cgroup
/dev/mapper/vg00-root 10G 4.2G 5.9G 42% /
/dev/nvme0n1p2 1014M 244M 771M 25% /boot
/dev/mapper/vg00-home 5.0G 80M 5.0G 2% /home #/home是单独的文件系统
/dev/nvme0n1p1 50M 6.8M 44M 14% /boot/efi
tmpfs 340M 0 340M 0% /run/user/0
[root@centos79 ~]# cd /home/ #切换到home目录
[root@centos79 home]# fuser -muv /home
USER PID ACCESS COMMAND
/home: root kernel mount (root)/home #第一行表示/home所在的文件系统的挂载点是/home
root 4436 ..c.. (root)bash
list open files
列出被进程所使用的文件名称,linux中一切(包括网络套接口)都是文件
相对于fuser是由文件或设备去找出使用该文件或设备的进程,lsof是根据进程找出使用的文件。
一.
lsof 文件 #显示系统上所有正与该文件交互的资源:包括用户、进程等。
[root@centos79 ~]# lsof /var/log/messages/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1178 root 5w REG 253,0 26409 9221425 /var/log/messages
二.
lsof [-aUu] [+d]
-a 使用多个选项时,需要【同时成立】才显示出结果,即对结果进行“与”运算,默认是“或”运算
-U 仅列出UNIX-like系统的socket文件类型
-u 后面接username,列出该使用者相关进程所使用的文件
-g 后面接gid,显示归属gid的进程情况
-l 在输出显示用户ID而不是用户名
-t 仅获取进程PID
-p 查看指定进程ID已打开的内容
-c 查看指定的命令正在使用的文件和网络连接
-d 后面接数字,显示FD为4的进程
+d 后面接目录,亦即找出某个目录下面已经被使用的文件
+D 同上,但是会搜索目录下的目录,时间较长
-r lsof会永远不断的执行,直到收到中断信号,默认15s刷新一次
+r lsof会一直执行,直到没有档案被显示,默认15s刷新一次
#列出使用者root 相关进程所使用的文件
[root@centos79 ~]# lsof -u root
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,0 224 128 /
systemd 1 root rtd DIR 253,0 224 128 /
systemd 1 root txt REG 253,0 1528712 668351 /usr/lib/systemd/systemd
systemd 1 root mem REG 253,0 570553 9193803 /etc/selinux/targeted/contexts/files/file_contexts.bin
systemd 1 root mem REG 253,0 203896 8616407 /usr/lib64/libnl-3.so.200.26.0
systemd 1 root mem REG 253,0 550896 8616415 /usr/lib64/libnl-route-3.so.200.26.0
systemd 1 root mem REG 253,0 138976 9072386 /usr/lib64/libibverbs.so.1.11.32.0
...
#列出除使用者root外的其他用户所使用的文件
[root@centos79 ~]# lsof -u ^root | more
COMMAND PID TID TASKCMD USER FD TYPE DEVICE SIZE/OFF NODE NAME
avahi-dae 901 avahi cwd DIR 253,0 71 9193598 /etc/avahi
avahi-dae 901 avahi rtd DIR 253,0 71 9193598 /etc/avahi
avahi-dae 901 avahi txt REG 253,0 203112 9193797 /usr/sbin/avahi-daemon
avahi-dae 901 avahi mem REG 253,0 880024 9072680 /usr/lib64/libnss_sss.so.2
...
#列出rsyslogd命令正在使用的文件和网络连接
[root@centos79 ~]# lsof -c rsyslogd
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1178 root cwd DIR 253,0 224 128 /
rsyslogd 1178 root rtd DIR 253,0 224 128 /
rsyslogd 1178 root txt REG 253,0 764040 9816104 /usr/sbin/rsyslogd
rsyslogd 1178 root mem REG 0,28 8388608 61 /run/log/journal/2dec64a1de7f4b84bfc20bb358a1c996/system.journal
rsyslogd 1178 root mem REG 253,0 70824 9816074 /usr/lib64/rsyslog/imjournal.so
rsyslogd 1178 root mem REG 253,0 71256 9816081 /usr/lib64/rsyslog/imuxsock.so
rsyslogd 1178 root mem REG 253,0 677448 9072678 /usr/lib64/libnss_myhostname.so.2
rsyslogd 1178 root mem REG 253,0 177232 8575641 /usr/lib64/libresolv-2.28.so
rsyslogd 1178 root mem REG 253,0 77688 8575635 /usr/lib64/libnss_dns-2.28.so
rsyslogd 1178 root mem REG 253,0 104440 8575637 /usr/lib64/libnss_files-2.28.so
rsyslogd 1178 root mem REG 253,0 70096 9816082 /usr/lib64/rsyslog/lmnet.so
...
#查看指定进程ID已打开的内容
[root@centos79 ~]# lsof -p 1178
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1178 root cwd DIR 253,0 224 128 /
rsyslogd 1178 root rtd DIR 253,0 224 128 /
rsyslogd 1178 root txt REG 253,0 764040 9816104 /usr/sbin/rsyslogd
rsyslogd 1178 root mem REG 0,28 8388608 61 /run/log/journal/2dec64a1de7f4b84bfc20bb358a1c996/system.journal
rsyslogd 1178 root mem REG 253,0 70824 9816074 /usr/lib64/rsyslog/imjournal.so
rsyslogd 1178 root mem REG 253,0 71256 9816081 /usr/lib64/rsyslog/imuxsock.so
...
#查看polkitd命令的pid
[root@centos79 ~]# lsof -t -c polkitd
905
三.
-i 后面不接任何内容,显示所有网络连接,-i后面可以接[46][protocol][@hostname|hostaddr][:service|port].
#-i [46]表示仅显示ipv4或ipv6.
[root@centos79 ~]# lsof -i 4
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
avahi-dae 901 avahi 15u IPv4 24056 0t0 UDP *:mdns
avahi-dae 901 avahi 17u IPv4 24058 0t0 UDP *:58930
chronyd 911 chrony 6u IPv4 22803 0t0 UDP localhost:323
sshd 952 root 5u IPv4 24640 0t0 TCP *:ssh (LISTEN)
cupsd 956 root 10u IPv4 24657 0t0 TCP localhost:ipp (LISTEN)
sshd 4430 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
sshd 4435 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
#-i [protocol]表示根据协议显示网络连接,TCP或UDP.
[root@centos79 ~]# lsof -i tcp
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 952 root 5u IPv4 24640 0t0 TCP *:ssh (LISTEN)
sshd 952 root 7u IPv6 24642 0t0 TCP *:ssh (LISTEN)
cupsd 956 root 9u IPv6 24656 0t0 TCP localhost:ipp (LISTEN)
cupsd 956 root 10u IPv4 24657 0t0 TCP localhost:ipp (LISTEN)
sshd 4430 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
sshd 4435 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
#-i [@hostname|hostaddr]来显示指定到指定主机的连接. 这对于检查是否开放连接到网络中或互联网上某个指定主机的连接时十分有用。
[root@centos79 ~]# lsof -i @centos79
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
NetworkMa 4067 root 26u IPv6 84898 0t0 UDP centos79:dhcpv6-client
sshd 4430 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
sshd 4435 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
[root@centos79 ~]# lsof -i @192.168.1.7
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 4430 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
sshd 4435 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
#-i [:service|port]来显示与指定服务或端口相关的网络信息,也可以通过端口搜索,可以方便找出什么阻止了另外一个应用绑定到指定端口。
[root@centos79 ~]# lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 952 root 5u IPv4 24640 0t0 TCP *:ssh (LISTEN)
sshd 952 root 7u IPv6 24642 0t0 TCP *:ssh (LISTEN)
sshd 4430 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
sshd 4435 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
[root@centos79 ~]# lsof -i :ssh
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 952 root 5u IPv4 24640 0t0 TCP *:ssh (LISTEN)
sshd 952 root 7u IPv6 24642 0t0 TCP *:ssh (LISTEN)
sshd 4430 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
sshd 4435 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
#使用-i @host:port显示基于主机与端口的连接
[root@centos79 ~]# lsof -i @192.168.1.9:22 #主机名centos79的IPv4就是192.168.1.9
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 4430 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
sshd 4435 root 5u IPv4 87951 0t0 TCP centos79:ssh->192.168.1.7:61578 (ESTABLISHED)
**knowledge: lsof结果解析**
1. USER: 进程所有者
2. FD: 文件描述符,应用程序通过文件描述符识别该文件,其中:
```
cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
lnn:library references (AIX);
er:FD information error (see NAME column);
jld:jail directory (FreeBSD);
ltx:shared library text (code and data);
mxx :hex memory-mapped type number xx.
m86:DOS Merge mapped file;
mem:memory-mapped file;
mmap:memory-mapped device;
pd:parent directory;
rtd:root directory;
tr:kernel trace file (OpenBSD);
v86 VP/ix mapped file;
0:表示标准输出
1:表示标准输入
2:表示标准错误
一般在标准输出、标准错误、标准输入后还跟着文件状态模式:
u:表示该文件被打开并处于读取/写入模式。
r:表示该文件被打开并处于只读模式。
w:表示该文件被打开并处于。
空格:表示该文件的状态模式为unknow,且没有锁定。
-:表示该文件的状态模式为unknow,且被锁定
```
3. TYPE(文件类型),其中:
```
REG:文件
DIR:表示目录。
CHR:表示字符类型。
BLK:块设备类型。
UNIX: UNIX 域套接字。
FIFO:先进先出 (FIFO) 队列。
IPv4:网际协议 (IP) 套接字
```
4. DEVICE: 以逗号分隔设备编号(磁盘名称)
5. SIZE: 文件的大小(bytes)
6. NODE: 索引节点(文件在磁盘上的标识)
7. NAME: 打开文件的确切名称
找出某个正在执行的进程pid
pidof -s 进程
-s 仅列出一个PID
[root@centos79 ~]# pidof rsyslogd
1178
#一、查看服务的状态
systemctl [command] [service.unit] #service.unit:一般服务类型,主要是系统服务,包括系统本身所需要的本地服务以及网络服务等,是最常见的unit类型,服务名称一般是以d结尾,如sshd,crond,atd,vsftpd,chronyd等,d表示daemon的意思
command:
start 立刻启动后面接的unit
stop 立刻关闭后面接的unit,如果用kill关闭一个正常运行的服务,systemd将会无法继续监控该服务,即systemctl将无法控制该服务
restart 立刻重新启动后面接的unit,即先stop再start
reload 不关闭后面接的unit的情况下,重新加载配置文件,让设置生效
enable 设置下次开机时,后面接的unit会被启动
disable 设置下次开机时,后面接的unit不会被启动
status 目前的unit的状态,会列出有没有正在执行,开机默认执行与否,登录等信息
is-active 目前有没有正在运行中
is-enabled 开机时有没有默认要启动这个unit
[root@centos79 ~]# systemctl status atd.service
● atd.service - Job spooling tools
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-12-17 18:32:53 EST; 1 weeks 5 days ago
Main PID: 1190 (atd)
Tasks: 1 (limit: 20972)
Memory: 444.0K
CGroup: /system.slice/atd.service
└─1190 /usr/sbin/atd -f
Dec 17 18:32:53 centos79 systemd[1]: Started Job spooling tools.
#第二行Loaded:这行在说明开机时这个unit会不会被启动,enabled为开机启动,disabled开机不会启动。其他状态:static:这个daemon不可以自己启动(不可enable),不过可能会被其他的enabled的服务唤醒(依赖属性的服务)。mask:这个daemon无论如何都无法被启动,因为已经被强制注销(非删除),可以通过systemctl unmask来改回默认状态【tips】
#第三行Active:这行说明这个unit的状态是否正在运行(running)或没有运行(dead)。常见的状态:active(running):正有一个或多个进程正在系统中运行的意思;active(exited):仅执行一次就正常结束的服务,目前并没有任何进程在系统中执行,例如,开机或是挂载时才会执行一次的quotan功能,就是这种模式,quotan不需要已知运行,只需执行一次之后,就交给文件系统自行处理,通常用bash shell写的小型服务,大多是属于这种类型(无需常驻内存)。active(waiting):正在运行当中,不过还需要等待其他的事件发生才能继续运行,例如,打印的队列相关服务就是这种状态,虽然正在启动中,不过,也需要真的有队列进来(打印作业)这样他才能继续唤醒打印机服务来进行下一步的打印功能。inactive:这个服务没有运行的意思。【tips】
#第三行Main PID:说明了了这个unit的PID
#最后一行说明了这个服务的日志文件信息,日志格式为:时间,信息发送主机,哪一个服务的信息,实际信息的内容
[root@centos79 ~]# systemctl disable chronyd.service
Removed /etc/systemd/system/multi-user.target.wants/chronyd.service. #禁止开机启动其实就是从/etc/systemd/system下面删除一条链接文件而已 【tips】
[root@centos79 ~]# systemctl enable chronyd.service
Created symlink /etc/systemd/system/multi-user.target.wants/chronyd.service → /usr/lib/systemd/system/chronyd.service. #开机启动就是建立一条符号链接 【tips】
#二、查看系统上所有的服务
systemctl [command] [--type=TYPE] [--all]
command:
systemctl 不接任何东西相当于systemctl list-units
list-units 显示目前正在运行的unit,若加上-all才会列出没有运行的
list-unit-files 依据/usr/lib/systemd/system/内的文件,将所有文件列表说明,即列出所有的unit,不管这些unit有没有正在运行,有没有开机启动
TYPE: service, socket, target, mount, automount, path, timer
[root@centos79 ~]# systemctl list-units --type=service --all
UNIT LOAD ACTIVE SUB DESCRIPTION >
accounts-daemon.service loaded inactive dead Accounts Service >
alsa-restore.service loaded inactive dead Save/Restore Sound Card State >
alsa-state.service loaded active running Manage Sound Card State (restore and store) >
atd.service loaded active running Job spooling tools >
auditd.service loaded active running Security Auditing Service >
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack >
blk-availability.service loaded inactive dead Availability of block devices >
bluetooth.service loaded active running Bluetooth service >
chronyd.service loaded active running NTP client/server >
● cpupower.service not-found inactive dead cpupower.service >
crond.service loaded active running Command Scheduler
...
#UNIT:项目的名称,包括unit的类别(看副文件名)
#LOAD:是否被加载
#ACTIVE:目前的状态,须与后续的SUB搭配查看
#DESCRIPUTION:详细描述
[root@centos79 ~]# systemctl list-unit-files
UNIT FILE STATE
proc-sys-fs-binfmt_misc.automount static
-.mount generated
boot-efi.mount generated
boot.mount generated
dev-hugepages.mount static
dev-mqueue.mount static
home.mount generated
proc-sys-fs-binfmt_misc.mount static
sys-fs-fuse-connections.mount static
sys-kernel-config.mount static
sys-kernel-debug.mount static
tmp.mount disabled
cups.path enabled
...
#STATE:是否开机启动
#三、切换不同的操作环境
systemctl [command] [unit.target]
command:
get-default 取得目前的target
set-default 设置后面接的target成为默认的操作模式
isolate 切换成后面接的模式
[root@centos79 ~]# systemctl list-units --type=target --all #列出所有的target unit
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
bluetooth.target loaded active active Bluetooth
cryptsetup.target loaded active active Local Encrypted Volumes
emergency.target loaded inactive dead Emergency Mode #紧急模式 在无法使用rescue.target模式时,可以使用这种模式
getty-pre.target loaded inactive dead Login Prompts (Pre)
getty.target loaded active active Login Prompts #可设置你需要几个tty之类的操作
graphical.target loaded inactive dead Graphical Interface #命令加上图形化界面,这个项目已经包含了下面的multi-user.target
initrd-fs.target loaded inactive dead Initrd File Systems
initrd-root-device.target loaded inactive dead Initrd Root Device
initrd-root-fs.target loaded inactive dead Initrd Root File System
initrd-switch-root.target loaded inactive dead Switch Root
initrd.target loaded inactive dead Initrd Default Target
local-fs-pre.target loaded active active Local File Systems (Pre)
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User System #纯命令行模式
...
rescue.target loaded inactive dead Rescue Mode #营救模式,在无法使用root登录的情况下,systemd在启动时会多加一个临时额外的系统,与原本的系统无关,这是你可以取得root的权限来维护你的系统
shutdown.target loaded inactive dead Shutdown #关机模式
[root@centos79 ~]# systemctl get-default
multi-user.target
[root@centos79 ~]# systemctl set-default multi-user.target #设置成默认命令行模式
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /usr/lib/systemd/system/multi-user.target.
[root@centos79 ~]# systemctl isolate graphical.target #在不重新启动的情况下,将目前的操作系统改为图形化模式
#其他模式:【tips】
systemctl [isolate] default 进入默认模式
systemctl [isolate] poweroff 系统关机
systemctl [isolate] reboot 重启
systemctl [isolate] suspend 进入挂起(暂停)模式,挂起(暂停)模式:将系统的状态数据保存到内存中,然后关闭大部分的系统硬件,并没有实际关机,当用户按下唤醒机器的按钮,系统数据会从内存中恢复,然后重新驱动被关闭的大部分硬件,然后开始正常运行,唤醒速度较快。
systemctl [isolate] hibernate 进入休眠模式,休眠模式:将系统的状态保存到硬盘中,保存完毕后,将计算机关机,当用户重新唤醒系统时,系统开始正常运行,然后将保存到硬盘中的系统状态恢复回来。
systemctl [isolate] rescue 强化进入救援模式
systemctl [isolate] emergency 强制进入紧急恢复模式
常见文件和目录
/var/log/message
/proc/cpuinfo
切换用户
su 用户名
su - 切换为root用户
${变量名}等价于$变量名
$(command)等价于`command`,表示command中的命令最先被执行,然后将执行的结果作为其他命令的参数。
export
下列文件的含义
-rw-------. 1 root root 5222 Dec 1 19:31 .bash_history
-rw-r–r–. 1 root root 18 May 11 2019 .bash_logout
-rw-r–r–. 1 root root 176 May 11 2019 .bash_profile
-rw-r–r–. 1 root root 176 May 11 2019 .bashrc