Linux Administration
Linux Administration
概述
对于日常办公使用的桌面电脑,大部分都是使用 Windows 操作系统;而对于提供系统应用的服务器,则大部分都是使用 Linux 操作系统。简单来说,Linux 就是一个操作系统,且是一个开源的操作系统。Linux 有很多发行版本,之前常用的免费发行版是 CentOS(Community Enterprise Operating System),Red Hat 改变对 CentOS 的发布策略后,可以使用 Rocky Linux 替代。
安装
作为服务器操作系统,一般在服务器上安装 Linux。学习时没有服务器怎么办,可以使用虚拟化软件来模拟服务器。常用的虚拟化软件有 VMware Workstation,Oracle VM VirtualBox。这里使用 VMware Workstation。
创建虚拟机
在官方网站下载并安装 VMware Workstation。安装后打开,界面如下,点击 “创建新的虚拟机”:
启动 “新建虚拟机向导” 来创建虚拟机,选择 “典型”,然后 “下一步”:
选择 “稍后安装操作系统”,然后 “下一步”:
客户机操作系统选择 “Linux”,版本选择 “CentOS 7 64 位”,然后 “下一步”:
指定虚拟机名称和位置,然后 “下一步”:
指定 “最大磁盘大小”,选择 “将虚拟磁盘存储为单个文件”,然后 “下一步”:
确认无误,点击 “完成”。
可以看到创建的虚拟机了。
安装 CentOS
在官方网站下载安装文件,也可以在阿里云镜像下载,这里下载 ISO 映像文件:CentOS-7-x86_64-DVD-2009.iso。
在 VMware Workstation 的 CentOS7 页面点击 “编辑虚拟机设置”,将内存修改为 2 GB:
选择下载的 ISO 映像文件后点击 “确定”:
然后点击 “开启此虚拟机”:
选择 “Install CentOS 7”,回车进行安装:
保持默认语言 “English”,点击 “Continue”:
点击 “DATE & TIME”,设置时区和日期时间:
“Region” 选择 “Asia”,“City” 选择 “Shanghai”,设置日期和时间后,点击 “Done”:
点击 “INSTALLATION DESTINATION”,设置安装位置:
这里先使用默认值,点击 “Done”:
点击 “NETWORK & HOST NAME”,设置网络:
启用网络,自动获取到 IP 地址:192.168.92.128,并设置主机名,点击 “Done”:
点击 “Begin Installation”:
开始安装:
安装完成,提示还需要完成一些配置:
点击 “ROOT PASSWORD”,设置 root
账户密码,如果密码太简单,则需要点击两次 “Done” 进行确认:
点击 “Finish configuration”,完成配置:
点击 “Reboot” 进行重启:
重启后,输入用户名 root
及其密码后进入命令行界面,就可以使用系统了。
连接 CentOS
在 VMware Workstation 中直接使用 CentOS 很不方便,可以使用终端工具连接到 CentOS 进行使用。常用的终端工具有:PuTTY,XShell 以及 SecureCRT 等。
这里使用 SecureCRT,在官方网站下载并安装后,创建到 CentOS 虚拟机的连接。其中,“Hostname“ 为前面自动获取的 IP 地址,“Username“ 为 root
,点击 “Connect”:
点击 “Accept & Save” 接受并保存密钥:
输入密码并勾选 “Save password”,点击 “OK”:
可以看到已经连接到 CentOS,进入命令行界面:
文件
本节主要介绍如何管理普通的目录和文件。
基础管理
在操作系统上,进行最多的工作就是管理目录和文件,包括创建,删除,修改,查看文件和目录。在 Linux 中一切皆文件,所有文件都在以 /
表示的根目录下。使用以下命令管理目录和文件。
tree
使用 tree
命令查看目录树。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install tree
查看系统一级目录:
[root@stone ~]# tree -L 1 /
/ #根目录
├── bin -> usr/bin #基本命令二进制文件
├── boot #引导程序文件
├── dev #设备文件
├── etc #配置文件
├── home #用户主目录
├── lib -> usr/lib #库文件
├── lib64 -> usr/lib64 #库文件
├── media #用于挂载可移动存储设备
├── mnt #临时挂载文件系统的目录
├── opt #第三方软件或应用程序安装目录
├── proc #虚拟文件系统,包含系统和进程信息
├── root #root 用户的主目录
├── run #运行时状态文件
├── sbin -> usr/sbin #系统管理二进制文件
├── srv #服务数据文件
├── sys #虚拟文件系统,用于访问和控制内核对象
├── tmp #临时文件
├── usr #应用程序、库文件和文档
└── var #可变数据
19 directories, 0 files
CentOS 的文件系统遵循 FHS 标准。
提示:
- 可以使用
Tab
键补全命令和目录。- 可以使用
man
命令查看其它命令的说明,例如man tree
,或者使用tree --help
。
其中:
-L
:指定目录最大深度,这里只显示 1 层。
ls
使用 ls
(list)命令查看目录和文件列表。
常用选项有:
选项 | 含义 |
---|---|
-a | 列出所有文件,包括隐藏文件(以 . 开头的文件) |
-l | 以详细格式列出(一般使用别名:ll ) |
-d | 列出目录信息 |
-h | 以可读方式显示文件大小 |
-i | 列出 Inode 节点索引号码 |
-r | 倒序列出 |
-R | 递归列出 |
-t | 按修改时间排列 |
查看当前目录下的所有目录和文件:
[root@stone ~]# ls -a
. .. anaconda-ks.cfg .bash_logout .bash_profile .bashrc .cshrc .tcshrc
查看指定目录下的所有目录和文件:
[root@stone ~]# ls -a /tmp/
. .. .font-unix .ICE-unix ks-script-i3ZLR4 .Test-unix .X11-unix .XIM-unix
查看以 .bash
开头的所有文件:
[root@stone ~]# ls .bash*
.bash_logout .bash_profile .bashrc
提示:
使用通配符
*
,匹配任意字符。
查看目录和文件详细信息:
[root@stone ~]# ls -la
dr-xr-x---. 3 root root 229 Jun 23 16:41 .
dr-xr-xr-x. 17 root root 224 Jun 22 20:39 ..
-rw-------. 1 root root 1227 Jun 22 20:40 anaconda-ks.cfg
-rw-------. 1 root root 1131 Jun 23 00:00 .bash_history
-rw-r--r--. 1 root root 18 Dec 29 2013 .bash_logout
-rw-r--r--. 1 root root 176 Dec 29 2013 .bash_profile
-rw-r--r--. 1 root root 176 Dec 29 2013 .bashrc
-rw-r--r--. 1 root root 100 Dec 29 2013 .cshrc
-rw-r--r--. 1 root root 129 Dec 29 2013 .tcshrc
其中:
- 第1 列
-rw-r--r--
:表示文件类型和权限 - 第 2 列
1
:表示链接数 - 第 3 列
root
:表示所属用户 - 第 4 列
root
:表示所属组 - 第 5 列
129
:表示大小 - 第 6 列
Dec 29 2013
:表示修改时间 - 第 7 列
.tcshrc
:表示文件名
pwd
使用 pwd
(print work directory)命令查看当前所在目录:
[root@stone ~]# pwd
/root
cd
使用 cd
(change directory)命令切换目录:
[root@stone ~]# cd /tmp/
[root@stone tmp]# pwd
/tmp
Linux 有一些特殊的目录名:
符号 | 含义 |
---|---|
. | 当前工作目录 |
.. | 父目录 |
~ | 用户主目录 |
- | 上个工作目录 |
切换到 root
用户主目录:
[root@stone ~]# cd ~
[root@stone ~]# pwd
/root
切换到父目录:
[root@stone ~]# cd ..
[root@stone /]# pwd
/
切换到上个工作目录:
[root@stone /]# cd -
/root
[root@stone ~]# pwd
/root
mkdir
使用 mkdir
(make directory)命令创建目录:
[root@stone ~]# mkdir d1
[root@stone ~]# ls
anaconda-ks.cfg d1
一次创建多个目录:
[root@stone ~]# mkdir d2 d3
[root@stone ~]# ls
anaconda-ks.cfg d1 d2 d3
使用 -p
选项创建多级目录:
[root@stone ~]# mkdir -p d4/d5
[root@stone ~]# ls /root/d4/
d5
touch
使用 touch
命令创建文件:
[root@stone ~]# touch f1
[root@stone ~]# ls
anaconda-ks.cfg d1 d2 d3 d4 f1
可以一次创建多个文件:
[root@stone ~]# touch f2 f3
[root@stone ~]# ls
anaconda-ks.cfg d1 d2 d3 d4 f1 f2 f3
cp
使用 cp
(copy)命令拷贝目录和文件。
常用选项有:
-r
:递归拷贝目录-a
:递归拷贝目录,保留文件的属性和链接
拷贝文件:
[root@stone ~]# cp f1 f1.bak
[root@stone ~]# ls f1*
f1 f1.bak
拷贝目录:
[root@stone ~]# cp -r d1 d1.bak
[root@stone ~]# ls
anaconda-ks.cfg d1 d1.bak d2 d3 d4 f1 f1.bak f2 f3
拷贝文件到目录:
[root@stone ~]# cp f1 d1/
[root@stone ~]# ls d1/
f1
拷贝目录,保留文件的属性和链接:
[root@stone ~]# cp -a /root /tmp
mv
使用 mv
(move)命令移动或者重命名文件和目录。
重命名文件:
[root@stone ~]# ls f2*
f2
[root@stone ~]# mv f2 f2.bak
[root@stone ~]# ls f2*
f2.bak
重命名目录:
[root@stone ~]# ls -d d2*
d2
[root@stone ~]# mv d2 d2.bak
[root@stone ~]# ls -d d2*
d2.bak
移动文件到目录:
[root@stone ~]# ls
anaconda-ks.cfg d1 d1.bak d2.bak d3 d4 f1 f1.bak f2.bak f3
[root@stone ~]# mv f3 d3
[root@stone ~]# ls d3
f3
移动目录到目录:
[root@stone ~]# ls
anaconda-ks.cfg d1 d1.bak d2.bak d3 d4 f1 f1.bak f2.bak
[root@stone ~]# mv d4 d3
[root@stone ~]# ls d3
d4 f3
[root@stone ~]# ls
anaconda-ks.cfg d1 d1.bak d2.bak d3 f1 f1.bak f2.bak
rmdir
使用 rmdir
(remove directory)命令删除空目录:
[root@stone ~]# ls
anaconda-ks.cfg d1 d2 d3 d4
[root@stone ~]# rmdir d1
[root@stone ~]# ls
anaconda-ks.cfg d2 d3 d4
rm
使用 rm
(remove)命令删除目录和文件。
删除文件:
[root@stone ~]# rm f2.bak
rm: remove regular empty file ‘f2.bak’? y
这里会提示你进行确认,实际上是使用了 alias
命令定义了 rm
命令的别名为 rm -i
:
[root@stone ~]# alias rm
alias rm='rm -i'
其中,-i
选项表示需要进行确认。可以使用 -f
选项强制删除而不需要确认。
[root@stone ~]# rm -f f1.bak
使用 -r
选项删除目录:
[root@stone ~]# rm -fr d3
一次性删除多个目录:
[root@stone ~]# rm -fr d1.bak d2.bak
chmod
使用 chmod
(change mode)命令修改目录和文件的权限。
Linux 中的每一个文件(包括目录)都有 r
(读)、w
(写)、x
(执行)三种权限,对于文件和目录,这三种权限的意义不一样,具体区别如下表:
权限 | 文件 | 目录 |
---|---|---|
r | 读取文件内容 | 只能读取目录中文件的文件名 |
w | 修改文件内容 | 修改目录中的文件(添加,删除文件等) |
x | 执行文件(针对可执行文件) | 进入目录 |
文件和目录的所有者可能是用户(user)、组(group)或者其他人(others),Linux 针对不同的所有者可以设置不同的权限,故每一个文件或者目录都有三组权限,分别为用户权限,组权限和其他人权限。
[root@stone ~]# ls -l f1
-rw-r--r--. 2 root root 0 Jun 22 22:14 f1
[root@stone ~]# ls -dl d1
drwxr-xr-x. 2 root root 16 Jun 22 22:21 d1
如上,其中 -rw-r--r--
的第 1 位 -
表示文件,如果为 d
表示目录,第 2-4 位 rw-
表示用户权限,第 5-7 位 r--
表示组权限,第 8-10 位 r--
表示其他人权限。
在 chmod
中可以分别使用 u
表示用户,g
表示组,o
表示其他人,a
表示所有人,+
表示增加权限,-
表示去掉权限,=
表示设置为该权限。
为所有人增加文件的执行权限:
[root@stone ~]# ls -l f1
-rw-r--r--. 2 root root 0 Jun 22 22:14 f1
[root@stone ~]# chmod a+x f1
[root@stone ~]# ls -l f1
-rwxr-xr-x. 2 root root 0 Jun 22 22:14 f1
权限可以采用三组八进制来表示,每一组内的字母对应的数值如下:
权限 | 数值 |
---|---|
r | 4 |
w | 2 |
x | 1 |
-(表示无权限) | 0 |
故字母表示的权限就可以换算成数字表示的权限了,如 -rw-r--r--
,就可以换算成 644
(4+2 4 4)。
修改文件的权限为 644
:
[root@stone ~]# ls -l f1
-rwxr-xr-x. 2 root root 0 Jun 22 22:14 f1
[root@stone ~]# chmod 644 f1
[root@stone ~]# ls -l f1
-rw-r--r--. 2 root root 0 Jun 22 22:14 f1
umask
使用 umask
命令设置权限掩码,用于指定新建文件或目录的默认权限。
[root@stone ~]# umask
0022
[root@stone ~]# umask -S
u=rwx,g=rx,o=rx
对于 root
用户,权限掩码默认为 0022
,表示对于组和其他人来说,是没有 w
权限的,那么
- 对于新建目录,默认权限为
drwxrwxrwx
-d----w--w-
=drwxr-xr-x
。 - 对于新建文件,默认权限为
-rw-rw-rw-
------w--w-
=-rw-r--r--
。
stat
使用 stat
命令查看目录和文件属性:
[root@stone ~]# stat d1
File: ‘d1’
Size: 16 Blocks: 0 IO Block: 4096 directory
Device: fd00h/64768d Inode: 16784340 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2023-06-22 22:21:19.597090507 +0800
Modify: 2023-06-22 22:21:14.198090426 +0800
Change: 2023-06-22 22:21:14.198090426 +0800
Birth: -
[root@stone ~]# stat f1
File: ‘f1’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 33575016 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2023-06-22 22:16:40.781086339 +0800
Modify: 2023-06-22 22:14:19.422084225 +0800
Change: 2023-06-22 22:14:19.422084225 +0800
Birth: -
各个属性的含义如下:
名称 | 含义 |
---|---|
Size | 目录或文件大小 |
Inode | Inode 编号,属性存储在 Inode 中 |
Links | 文件链接数 |
Access | 文件权限 |
Uid | 用户 ID |
Gid | 组 ID |
Access | 最近一次访问目录或文件的时间 |
Modify | 最近一次修改目录或文件内容的时间 |
Change | 最近一次改变目录或文件属性的时间 |
ln
使用 ln
命令创建链接,Linux 中的链接有两类:
- 硬链接
- 只能用于文件,不能用于目录,适用于不同用户对同一文件的访问。
- 创建硬链接后文件链接数都增加 1。
- 两个文件名对应同一个 Inode 节点和文件内容。
- 删除一个文件名只是脱链一个文件,另一个还有效。
- 使用命令
ln
创建硬链接。
创建硬链接:
[root@stone ~]# ln f1 f1_h
[root@stone ~]# ll f1*
-rw-r--r--. 2 root root 0 Jun 22 22:14 f1
-rw-r--r--. 2 root root 0 Jun 22 22:14 f1_h
[root@stone ~]# stat f1
File: ‘f1’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 33575016 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2023-06-22 22:16:40.781086339 +0800
Modify: 2023-06-22 22:14:19.422084225 +0800
Change: 2023-06-22 23:46:58.775167337 +0800
Birth: -
[root@stone ~]# stat f1_h
File: ‘f1_h’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 33575016 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2023-06-22 22:16:40.781086339 +0800
Modify: 2023-06-22 22:14:19.422084225 +0800
Change: 2023-06-22 23:46:58.775167337 +0800
Birth: -
可以看到这两个文件的 Inode 相同,Links 都为 2。
软连接
可以用于文件和目录,相当于 Windows 中的快捷方式。
创建软链接后文件链接数保持不变。
两个文件名对应 2 个 Inode 节点和文件内容。
删除原始文件会导致空链接。
使用命令
ln -s
创建软连接。
创建软连接:
[root@stone ~]# touch f2
[root@stone ~]# ln -s f2 f2_s
[root@stone ~]# ll f2*
-rw-r--r--. 1 root root 0 Jun 22 23:52 f2
lrwxrwxrwx. 1 root root 2 Jun 22 23:52 f2_s -> f2
[root@stone ~]# stat f2
File: ‘f2’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 33575038 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2023-06-22 23:52:28.694172269 +0800
Modify: 2023-06-22 23:52:28.694172269 +0800
Change: 2023-06-22 23:52:28.694172269 +0800
Birth: -
[root@stone ~]# stat f2_s
File: ‘f2_s’ -> ‘f2’
Size: 2 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 33575039 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2023-06-22 23:52:51.119172604 +0800
Modify: 2023-06-22 23:52:51.119172604 +0800
Change: 2023-06-22 23:52:51.119172604 +0800
Birth: -
可以看到这两个文件的 Inode 不同,Links 都为 1。
unlink
使用 unlink
命令删除软连接。
[root@stone ~]# unlink f2_s
find
使用 find
命令查找目录和文件。
常用选项有:
选项 | 含义 |
---|---|
-name | 指定目录或者文件名 |
-type | 指定文件类型,可以是 f (文件),d (目录),l (链接) |
-size | 指定文件大小,+ 为大于,- 为小于,单位可以是 c (字节)、w (字数)、b (块数)、k (KB)、M (MB)或 G (GB) |
-mtime -mmin | 指定修改时间,以天或分为单位,+ 为时间之前,- 为时间之内 |
-maxdepth -mindepth | 指定最大或最小搜索目录深度 |
-perm | 指定权限 |
-user | 指定文件所有者 |
-group | 指定文件所属组 |
查找 /var/log
目录下扩展名为 .log
的文件:
[root@stone ~]# find /var/log/ -name *.log
/var/log/tuned/tuned.log
/var/log/audit/audit.log
/var/log/anaconda/anaconda.log
/var/log/anaconda/X.log
/var/log/anaconda/program.log
/var/log/anaconda/packaging.log
/var/log/anaconda/storage.log
/var/log/anaconda/ifcfg.log
/var/log/anaconda/ks-script-l1NlL6.log
/var/log/anaconda/ks-script-yfcGhw.log
/var/log/anaconda/journal.log
/var/log/boot.log
/var/log/yum.log
查找 /var/log
目录下的目录:
[root@stone ~]# find /var/log/ -type d
/var/log/
/var/log/tuned
/var/log/audit
/var/log/anaconda
/var/log/rhsm
查找 /var/log
目录下大于 1 MB 的文件:
[root@stone ~]# find /var/log/ -size +1M
/var/log/anaconda/journal.log
查找 /var/log
目录下在 60 分钟内修改过的文件:
[root@stone ~]# find /var/log -mmin -60
/var/log/audit/audit.log
/var/log/messages
/var/log/cron
查找 /tmp
目录下权限为 700
的文件:
[root@stone ~]# find /tmp/ -perm 700
/tmp/ks-script-i3ZLR4
还可以使用 -exec
选项对查找出来的文件执行指定的命令:
[root@stone ~]# find /var/log -mmin -60 -exec ls -l {} \;
-rw-------. 1 root root 204134 Jun 23 15:20 /var/log/audit/audit.log
-rw-------. 1 root root 348712 Jun 23 15:20 /var/log/messages
-rw-------. 1 root root 4212 Jun 23 15:01 /var/log/cron
其中,{}
表示查找结果,\;
表示命令结束。
rename
使用 rename
批量重命名文件。
语法:
rename [options] expression replacement file...
[root@stone ~]# touch f00.txt f01.txt f02.txt
[root@stone ~]# rename .txt .txt.bak f0*.txt
[root@stone ~]# ls *.txt.bak
f00.txt.bak f01.txt.bak f02.txt.bak
编辑和查看文件
在 Linux 操作系统上,很少去创建编辑类似 Word,Excel 这类文档,大部分处理的都是纯文本文件。本节主要介绍如何创建,编辑和查看文件。
vim
使用 vi
或者 vim
来创建和编辑文本。在所有的 Linux 发行版本都有提供 vi
这个文本编辑器,vim
是 vi
的增强版本。这里使用 vim
来演示如何创建和编辑文本。
vim
有三种模式:
- 一般模式:输入
vim
命令后进入的就是一般模式,编辑模式和命令模式下按Esc
键进入一般模式。 - 编辑模式:在一般模式下按
i
,I
,o
,O
,a
,A
,r
,R
,s
,S
,c
,C
键进入编辑模式,可在此模式键入文字。 - 命令模式:在一般模式下按
:
,/
,?
键进入命令模式,可在此模式键入命令。
在一般模式下,可以对文本进行移动光标,选择,复制,粘帖,删除等操作。
动作 | 按键 |
---|---|
移动光标 1 个字符 | ↑ ,↓ ,← ,→ 或者 k ,j ,h ,l 或者空格;前面可加数字表示移动多个字符 |
移动光标 1 页 | PgUp ,PgDn 或者 Ctrl + f ,Ctrl + b |
移动光标半页 | Ctrl + d ,Ctrl + u |
移动到行首 | Home ,0 (数字 0) |
移动到行尾 | End ,$ |
移动到当前屏幕最上方第 1 个字符 | H (High) |
移动到当前屏幕最下方第 1 个字符 | L (Low) |
移动到当前屏幕中间行第 1 个字符 | M (Middle) |
移动到文本最后 1 行 | G 或者 }} |
移动到文本第 1 行 | gg 或者 {{ |
移动到文本的第 n 行 | nG (n 为数字) |
向下移动 n 行 | n + Enter (n 为数字) |
向右移动 n 列 | n + Space (n 为数字) |
选择字符或行 | v 或者 V |
选择块 | Ctrl + v |
选择全部文本 | ggVG |
复制一行或多行 | yy 或者 nyy (n 为数字) |
复制该行到首行或到尾行的行 | ygg 或者 yG |
复制光标到行首或行尾的字符 | y0 或者 y$ |
粘帖到当前行下面或上面 | p 或者 P |
向后或向前删除 1 个字符 | x 或者 X |
向后或向前删除 n 个字符 | nx 或者 nX (n 为数字) |
删除 1 行或者 n 行 | dd 或者 ndd (n 为数字) |
删除该行到首行或到尾行的行 | dgg 或者 dG |
删除光标到行首或行尾的字符 | d0 (光标所在字符保留)或者 d$ (光标所在字符不保留) |
撤销 | u |
重做 | Ctrl + r |
重复前一个动作 | . |
在一般模式下,切换到编辑模式的动作与按键:
动作 | 按键 |
---|---|
在当前字符前面或者在当前行第 1 个非空白字符前插入 | i 或者 I |
在当前字符后面或者在当前行最后面插入 | a 或者 A |
在当前行下面或者上面插入 | o 或者 O |
在一般模式下,切换到命令模式的动作与按键:
动作 | 按键 |
---|---|
搜索 | /str :向下搜索字符串 str ,使用 n 或者 N 继续向下或者向上搜索?str :向上搜索字符串 str ,使用 n 或者 N 继续向上或者向下搜索 |
替换 | :n1,n2s/str1/str2/g :表示将 n1 到 n2 行之间的 str1 替换为 str2:1,$s/str1/str2/g :表示将文件中所有的 str1 替换为 str2:1,$s/str1/str2/gc :替换前需要确认 |
读入 | :r filename :读取文件添加到当前光标行下 |
执行 | :! command :执行操作系统命令 |
设置 | :set nu :设置行号:set hlsearch :设置高亮搜索结果 |
保存 | :w :保存:w filename :另存为:n1,n2 w filename :将 n1 行到 n2 行之间内容另存为 |
退出 | :q :没有修改,直接退出:q! :放弃修改,强制退出:wq :保存修改再退出 |
cat
使用 cat
命令查看文件内容。
查看系统版本:
[root@stone ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
查看内核版本:
[root@stone ~]# cat /proc/version
Linux version 3.10.0-1127.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ) #1 SMP Tue Mar 31 23:36:51 UTC 2020
使用 -n
选项为输入增加行号:
[root@stone ~]# cat -n .bash_profile
1 # .bash_profile
2
3 # Get the aliases and functions
4 if [ -f ~/.bashrc ]; then
5 . ~/.bashrc
6 fi
7
8 # User specific environment and startup programs
9
10 PATH=$PATH:$HOME/bin
11
12 export PATH
more
使用 cat
命令会将文件内容全部输出,如果文件内容太长,则有可能看不到前面的内容,可以使用 more
命令来分页查看。
[root@stone ~]# more .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
在 more
命令中可以使用的按键有:
按键 | 含义 |
---|---|
space (空格键) | 向下翻页 |
b | 向上翻页 |
Enter (回车键) | 向下翻一行 |
/str | 向下搜索 str ,再按 n 重复向下搜索 |
:f | 显示文件名及当前行号 |
q | 退出 |
less
除了使用 more
,还可以使用功能更多的 less
命令来分页查看文件。
[root@stone ~]# less /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
在 less
命令中可以使用的按键有:
按键 | 含义 |
---|---|
space (空格键),PgDn (下页) | 向下翻页 |
b ,PgUp (上页) | 向上翻页 |
Enter (回车键) | 向下翻一行 |
g ,G | 移动到文件的首页或者尾页 |
/str | 向下搜索 str ,再按 n 或者 N 重复向下或向上搜索 |
?str | 向上搜索 str ,再按 n 或者 N 重复向上或向下搜索 |
:f | 显示文件名及当前页行号 |
q | 退出 |
head
使用 head
命令查看文件前面指定行的内容,默认为 10 行。
[root@stone ~]# head /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
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
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
使用 -n
选项指定行数:
[root@stone ~]# head -n 2 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@stone ~]# head -2 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
如果指定的行数为负数,则不显示文件最后面的这些行:
[root@stone ~]# head -n -15 /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
如果要一次查看多个文件,可以使用 -q
选项指定不显示文件名:
[root@stone ~]# head -2 /etc/passwd /etc/group
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
==> /etc/group <==
root:x:0:
bin:x:1:
[root@stone ~]# head -2 -q /etc/passwd /etc/group
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
root:x:0:
bin:x:1:
tail
使用 tail
命令查看文件后面指定行的内容,默认为 10 行。
[root@stone ~]# tail /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
使用 -n
选项指定行数:
[root@stone ~]# tail -n 2 /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
[root@stone ~]# tail -2 /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
如果指定的行数为正数,则不显示文件最前面的这些行:
[root@stone ~]# tail -n +15 /etc/passwd
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
使用 -f
选项保持文件处于打开状态,不断显示新添加的行,经常用于查看日志的实时变化:
[root@stone ~]# tail -5f /var/log/messages
Jun 23 17:54:34 stone dhclient[4059]: bound to 192.168.92.128 -- renewal in 713 seconds.
Jun 23 17:54:34 stone dbus[644]: [system] Successfully activated service 'org.freedesktop.nm_dispatcher'
Jun 23 17:54:34 stone systemd: Started Network Manager Script Dispatcher Service.
Jun 23 17:54:34 stone nm-dispatcher: req:1 'dhcp4-change' [ens33]: new request (2 scripts)
Jun 23 17:54:34 stone nm-dispatcher: req:1 'dhcp4-change' [ens33]: start running ordered scripts...
nl
使用 nl
(number lines)命令查看文件内容,并加上行号。
常用选项有:
-b
:指定标记行号的方式,包括:a
:为所有行标记行号t
:为非空行标记行号
-n
:指定格式,包括:ln
:行号在内容左边rn
:行号在内容右边
-w
:行号占用的位数,默认为 6 位
[root@stone ~]# nl -b a .bash_profile
1 # .bash_profile
2
3 # Get the aliases and functions
4 if [ -f ~/.bashrc ]; then
5 . ~/.bashrc
6 fi
7
8 # User specific environment and startup programs
9
10 PATH=$PATH:$HOME/bin
11
12 export PATH
wc
使用 wc
命令统计文件词数和行数。
[root@stone ~]# wc .bash_profile
12 27 176 .bash_profile
其中,12
为行数,27
为词数,176
为字节数。
使用 -l
选项只统计行数:
[root@stone ~]# wc -l .bash_profile
12 .bash_profile
cut
使用 cut
命令对文件内容进行列分割,不影响原文件。默认使用 Tab
进行分割,使用 -d
选项指定分隔符,使用 -f
选项指定需要显示的列。
[root@stone ~]# cut -d ' ' -f 1,4 /etc/redhat-release
CentOS 7.9.2009
sort
使用 sort
命令对文件内容进行排序,不影响原文件。
常用选项有:
-f
:忽略大小写-n
:按照数字大小排序-r
:反向排序-u
:去除重复值-t
:指定分隔符,默认使用Tab
进行分割-k
:指定排序列-o
:输出到文件
[root@stone ~]# sort -t ':' -k 3 -n /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
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
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
uniq
使用 uniq
命令对文件内容进行去重,不影响原文件。
常用选项有:
-c
:显示该行重复出现的次数-d
:只输出重复行-u
:只输出不重复行-i
:忽略大小写-s N
:忽略前面 N 个字符
创建一个文件然后去重:
[root@stone ~]# vim uniq.txt
1
2
2
3
3
3
4
[root@stone ~]# uniq -c -d uniq.txt
2 2
3 3
[root@stone ~]# uniq -c -u uniq.txt
1 1
1 4
[root@stone ~]# uniq -c uniq.txt
1 1
2 2
3 3
1 4
压缩与打包
在 Linux 上有很多压缩工具,这里只介绍常用的几种。
zip
使用 zip
命令压缩目录和文件,压缩文件以 .zip
为文件后缀名。
常用选项有:
-r
:压缩目录。-q
:静默操作,不显示压缩过程。-d
:从压缩文件内删除指定的文件。-f
:更新现有文件。-u
:更新指定文件,如果压缩文件中没有此文件,则增加到压缩文件。-j
:不包含目录。
使用 unzip
命令解压 .zip
文件。
常用选项有:
-l
:列出压缩文件中的内容。-v
:列出压缩文件中的内容,更详细信息。-d
:解压到指定目录。-o
:覆盖现有文件而不提示。
压缩当前目录下所有以 f
开头的文件:
[root@stone ~]# zip f.zip f*
adding: f1 (stored 0%)
adding: f1_h (stored 0%)
adding: f2 (stored 0%)
adding: f2_s (stored 0%)
adding: f3.txt (stored 0%)
adding: f4 (deflated 52%)
[root@stone ~]# ll f.zip
-rw-r--r--. 1 root root 939 Jul 2 12:44 f.zip
[root@stone ~]# unzip -l f.zip
Archive: f.zip
Length Date Time Name
--------- ---------- ----- ----
0 06-22-2023 22:14 f1
0 06-22-2023 22:14 f1_h
0 06-22-2023 23:52 f2
0 06-22-2023 23:52 f2_s
13 06-23-2023 16:41 f3.txt
200 06-23-2023 13:45 f4
--------- -------
213 6 files
[root@stone ~]# unzip -v f.zip
Archive: f.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
0 Stored 0 0% 06-22-2023 22:14 00000000 f1
0 Stored 0 0% 06-22-2023 22:14 00000000 f1_h
0 Stored 0 0% 06-22-2023 23:52 00000000 f2
0 Stored 0 0% 06-22-2023 23:52 00000000 f2_s
13 Stored 13 0% 06-23-2023 16:41 011de4af f3.txt
200 Defl:N 96 52% 06-23-2023 13:45 0c43bcd0 f4
-------- ------- --- -------
213 109 49% 6 files
从压缩文件中删除文件:
[root@stone ~]# zip -d f.zip f4
deleting: f4
[root@stone ~]# unzip -v f.zip
Archive: f.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
0 Stored 0 0% 06-22-2023 22:14 00000000 f1
0 Stored 0 0% 06-22-2023 22:14 00000000 f1_h
0 Stored 0 0% 06-22-2023 23:52 00000000 f2
0 Stored 0 0% 06-22-2023 23:52 00000000 f2_s
13 Stored 13 0% 06-23-2023 16:41 011de4af f3.txt
-------- ------- --- -------
13 13 0% 5 files
静默压缩目录:
[root@stone ~]# zip -r -q d1.zip d1/
[root@stone ~]# ll d1.zip
-rw-r--r--. 1 root root 294 Jul 2 11:44 d1.zip
[root@stone ~]# unzip -l d1.zip
Archive: d1.zip
Length Date Time Name
--------- ---------- ----- ----
0 06-22-2023 22:21 d1/
0 06-22-2023 22:21 d1/f1
--------- -------
0 2 files
修改文件后,更新压缩文件:
[root@stone ~]# echo "Hello Stone" > d1/f1
[root@stone ~]# zip -f d1.zip
freshening: d1/ (stored 0%)
freshening: d1/f1 (stored 0%)
[root@stone ~]# unzip -l d1.zip
Archive: d1.zip
Length Date Time Name
--------- ---------- ----- ----
0 07-02-2023 12:47 d1/
12 07-02-2023 12:47 d1/f1
--------- -------
12 2 files
增加文件后,更新压缩文件:
[root@stone ~]# touch d1/f2
[root@stone ~]# echo "Hello CentOS" > d1/f2
[root@stone ~]# zip -u d1.zip d1/f2
adding: d1/f2 (stored 0%)
[root@stone ~]# unzip -l d1.zip
Archive: d1.zip
Length Date Time Name
--------- ---------- ----- ----
0 07-02-2023 12:50 d1/
12 07-02-2023 12:47 d1/f1
13 07-02-2023 12:51 d1/f2
--------- -------
25 3 files
解压到指定目录:
[root@stone ~]# unzip d1.zip -d /tmp/
Archive: d1.zip
creating: /tmp/d1/
extracting: /tmp/d1/f1
extracting: /tmp/d1/f2
extracting: /tmp/d1/f3
再次解压,覆盖现有文件而不提示:
[root@stone ~]# unzip -o d1.zip -d /tmp/
Archive: d1.zip
extracting: /tmp/d1/f1
extracting: /tmp/d1/f2
extracting: /tmp/d1/f3
如果要解压多个 zip
文件,直接使用 *.zip
会报错:
[root@stone ~]# unzip *.zip -d /tmp/
Archive: d1.zip
caution: filename not matched: f.zip
可以使用 \*.zip
,'*.zip'
或者 "*.zip"
:
[root@stone ~]# unzip \*.zip -d /tmp/
[root@stone ~]# unzip '*.zip' -d /tmp/
[root@stone ~]# unzip "*.zip" -d /tmp/
gzip
使用 gzip
命令压缩文件,压缩文件以 .gz
为文件后缀名。
常用选项有:
-c
:将压缩文件输出到标准输出中,并保留源文件。-r
:递归压缩指定目录以及子目录下的所有文件。-l
:列出压缩文件内容。-d
:解压缩。
默认情况下,gzip
压缩文件后,源文件就消失了。
[root@stone ~]# ls uniq.*
uniq.txt
[root@stone ~]# gzip uniq.txt
[root@stone ~]# ls uniq.*
uniq.txt.gz
使用 -c
选项及重定向,可以保留源文件。
[root@stone ~]# gzip -c f1 > f1.gz
[root@stone ~]# ls f1*
f1 f1.gz
gzip
不能压缩目录,使用 -r
选项也只是压缩目录里面的文件。
[root@stone ~]# ls d1
f1 f2 f3
[root@stone ~]# gzip -r d1/
[root@stone ~]# ls d1
f1.gz f2.gz f3.gz
使用 -l
选项查看压缩文件内容。
[root@stone ~]# gzip -l uniq.txt.gz
compressed uncompressed ratio uncompressed_name
38 14 21.4% uniq.txt
使用 -d
选项解压缩。
[root@stone ~]# gzip -d uniq.txt.gz
[root@stone ~]# ls uniq.*
uniq.txt
[root@stone ~]# gunzip -d -r d1/
[root@stone ~]# ls d1/
f1 f2 f3
可以使用 zcat
命令查看压缩文件里面的内容而无需解压。
[root@stone ~]# gzip uniq.txt
[root@stone ~]# zcat uniq.txt.gz
1
2
2
3
3
3
4
如果文件内容很多,还可以使用 zmore
或者 zless
翻页查看,zgrep
搜索内容。
tar
使用 tar
命令打包多个目录和文件,再使用 gzip
进行压缩。
常用选项有:
-c
:创建打包文件。-t
:列出打包文件内容。-x
:还原打包文件中。-v
:显示处理过程。-z
:使用gzip
处理打包文件。-f
:指定打包文件名。-C
:指定还原目录。
打包并压缩目录,然后查看打包文件里面的内容。
[root@stone ~]# tar -cvzf d1.tar.gz d1
d1/
d1/f1
d1/f2
d1/f3
查看打包文件。
[root@stone ~]# tar -tvzf d1.tar.gz
drwxr-xr-x root/root 0 2023-07-02 21:04 d1/
-rw-r--r-- root/root 12 2023-07-02 12:47 d1/f1
-rw-r--r-- root/root 13 2023-07-02 12:51 d1/f2
-rw-r--r-- root/root 0 2023-07-02 12:58 d1/f3
还原打包文件到指定目录。
[root@stone ~]# tar -xvzf d1.tar.gz -C /tmp/
d1/
d1/f1
d1/f2
d1/f3
Bash
前面在使用 ls -a
命令查看 /root
目录下的文件时,发现有一些包含 bash
的文件,本节就介绍什么是 Bash。
简介
Linux 操作系统的核心称为内核,用于与计算机硬件交互。作为用户,无法直接操作内核,需要使用称为 Shell 的程序与内核进行交互。Shell 有很多种,比如 Bourne Again shell(bash),C Shell(csh),K Shell(ksh),Z Shell(zsh) 等,CentOS 使用 Bash 作为默认 Shell。
使用终端工具连接到 CentOS 进入命令行环境后,就会看到如下 Shell 提示符:
[root@stone ~]#
其中:
root
:表示用户名stone
:表示主机名~
:表示当前位于用户主目录#
:表示用户为root
,如果是其它用户,则为$
如果默认的 Shell 不是 Bash,可以使用 bash
命令启动:
[root@stone ~]# bash
使用 --version
选项查看 Bash 版本:
[root@stone ~]# bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
使用 exit
命令退出 Bash:
[root@stone ~]# exit
echo
使用 echo
命令在命令行输出文本,变量值或者命令的执行结果。
常用选项有:
-e
:启用反斜线转义符
常用转义字符有:
\\
:backslash\a
:alert (BEL)\b
:backspace\c
:produce no further output\e
:escape\f
:form feed\n
:new line\r
:carriage return\t
:horizontal tab\v
:vertical tab\0NNN
:byte with octal value NNN (1 to 3 digits)\xHH
:byte with hexadecimal value HH (1 to 2 digits)
[root@stone ~]# echo Hello,CentOS
Hello,CentOS
[root@stone ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@stone ~]# echo `date`
Tue Jun 27 22:27:18 CST 2023
[root@stone ~]# echo -e "Hello Linux\nHello World"
Hello Linux
Hello World
快捷键
Bash 常用快捷键如下(不区分大小写):
Ctrl + A
:移到行首。Ctrl + E
:移到行尾。Ctrl + L
:清除屏幕并将当前行移到页面顶部。Ctrl + C
:中止当前正在执行的命令。Ctrl + Z
:将执行的命令放入 Shell 后台并暂停。Shift + PageUp
:向上滚动。Shift + PageDown
:向下滚动。Ctrl + U
:从光标位置删除到行首。Ctrl + K
:从光标位置删除到行尾。Ctrl + W
:删除光标位置前一个单词。Ctrl + D
:关闭 Shell 会话。↑
,↓
:浏览已执行命令的历史记录。Tab
:自动补全命令和路径。Esc + .
:插入上一个命令的最后一个词。Ctrl + R
:键入命令的部分字符,自动在历史文件中查询并显示最近一条匹配的结果,按下回车执行。
符号
Bash 中有很多具有特定含义的符号。
;
使用;
(分号)表示命令结束,这样就可以在一行上放置多个命令。
[root@stone ~]# cd /root;ls
无论前一个命令是否执行成功,后面的命令都会执行。
&&
对于 Command1 && Command2
,如果 Command1
命令执行成功,才会执行 Command2
。
[root@stone ~]# ls f3.txt && cat f3.txt
f3.txt
Hello,CentOS
上面例子中,只有 ls f3.txt
命令执行成功,才会执行 cat f3.txt
。
[root@stone ~]# ls f4.txt && cat f3.txt
ls: cannot access f4.txt: No such file or directory
上面例子中,由于 ls f4.txt
命令执行失败,故不会执行 cat f3.txt
。
||
对于 Command1 || Command2
,即使 Command1
命令执行失败,也会执行 Command2
。
[root@stone ~]# ls f4.txt || cat f3.txt
ls: cannot access f4.txt: No such file or directory
Hello,CentOS
上面例子中,ls f4.txt
命令执行失败了,但也会执行 cat f3.txt
。
~
使用 ~
(波浪线)表示当前用户的主目录。
[root@stone ~]# ls -d ~
/root
?
使用 ?
(问号)匹配文件路径中单个字符。不能匹配路径分隔符(/
)。
[root@stone ~]# ls d?/f1
d1/f1
[root@stone ~]# ls d1/f?
d1/f1
[root@stone ~]# ls f?
f1 f2 f4
[root@stone ~]# ls f???
f1_h f2_s
*
使用 *
(星号)匹配文件路径中任意个字符。不能匹配路径分隔符(/
)。
[root@stone ~]# ls f*
f1 f1_h f2 f2_s f3.txt f4
[root@stone ~]# ls *.txt
f3.txt uniq.txt
[]
使用 []
(方括号)匹配方括号中所有字符。
[root@stone ~]# ls f[12]
f1 f2
在 []
最前面使用 ^
或者 !
表示反向匹配。
[root@stone ~]# ls [!adu]*
f1 f1_h f2 f2_s f3.txt f4
在 []
最里面使用 -
表示连续的范围。
[root@stone ~]# ls f[1-5]
f1 f2 f4
[root@stone ~]# ls f[!2-9]*
f1 f1_h
{}
使用 {}
(大括号)匹配大括号中的所有值,以逗号分隔。
[root@stone ~]# ls {f3,uniq}.txt
f3.txt uniq.txt
在 {}
里面使用 ..
表示连续的范围。
[root@stone ~]# ls f{1..4}
ls: cannot access f3: No such file or directory
f1 f2 f4
$
使用 $
引用变量。
[root@stone ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
变量除了可以放在 $
后面,还可以放在 ${}
里面。
[root@stone ~]# echo ${USER}
root
当前 Shell 的 PID:
[root@stone ~]# echo $$
7706
$()
使用 $()
获取命令结果。
[root@stone ~]# echo $(date)
Wed Jun 28 21:09:06 CST 2023
也可以将命令放在反引号中。
[root@stone ~]# echo `date`
Wed Jun 28 21:23:25 CST 2023
$(())
使用 $(())
获取整数运算结果。
[root@stone ~]# echo $((60*60*24*7))
604800
\
使用 \
(反斜杠)转义特殊字符。
[root@stone ~]# echo \$PATH
$PATH
当按下 Enter
键,表示命令结束,开始执行。如果命令太长,需要换行显示,此时可以使用 \
对 Enter
进行转义,使其变成一个普通字符,Bash 会将其当作长度为 0
的空字符处理,从而可以将一行命令写成多行。
[root@stone ~]# ls /root/f1 /root/f2* \
> /root/f3*
/root/f1 /root/f2 /root/f2_s /root/f3.txt
'
使用 '
(单引号)显示字符,各种特殊字符在单引号里面,都会变为普通字符。
[root@stone ~]# echo '$PATH'
$PATH
[root@stone ~]# echo '$((60*60*24*7))'
$((60*60*24*7))
"
使用 "
(双引号)显示字符,与单引号类似,但对于 $
,`
和 \
,仍保留特殊含义。
[root@stone ~]# echo "$PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@stone ~]# echo "`date`"
Wed Jun 28 21:45:38 CST 2023
重定向
Linux 重定向是一种将命令的输入或输出从默认位置更改为另一个位置的方法。可以使用重定向符号将命令的输出发送到文件中,或者将文件中的内容作为命令的输入。例如,使用 >
符号可以将命令的输出重定向到一个文件中,而使用 <
符号可以将文件中的内容作为命令的输入。
在 Linux 中,每个进程都有三个标准流:标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。
标准输入(stdin)是进程从用户读取输入数据的流,对应的文件描述符位 0。默认情况下,stdin 连接到键盘(即用户输入)。
标准输出(stdout)是进程输出数据的流,对应的文件描述符位 1。默认情况下,stdout 连接到终端(即屏幕)。
标准错误(stderr)是进程输出错误信息的流,对应的文件描述符位 2。默认情况下,stderr 连接到终端(即屏幕)。
可以使用重定向符号将这些流重定向到其他位置,例如将 stdout 重定向到文件中。
输出重定向
使用 >
(覆盖)或者 >>
(追加)对输出进行重定向。
[root@stone ~]# ls > ls.txt
[root@stone ~]# cat ls.txt
anaconda-ks.cfg
d1
f1
f1_h
f2
f2_s
f3.txt
f4
ls.txt
uniq.txt
[root@stone ~]# ls f1 > ls.txt
[root@stone ~]# cat ls.txt
f1
[root@stone ~]# ls f2 >> ls.txt
[root@stone ~]# cat ls.txt
f1
f2
以上是对标准输出(stdout)的重定向,还可以对标准错误(stderr)重定向。
[root@stone ~]# ls f5 2>lserr.txt
[root@stone ~]# cat lserr.txt
ls: cannot access f5: No such file or directory
[root@stone ~]# ls f6 2>>lserr.txt
[root@stone ~]# cat lserr.txt
ls: cannot access f5: No such file or directory
ls: cannot access f6: No such file or directory
同时对标准输出(stdout)和标准错误(stderr)重定向。
[root@stone ~]# ls f1 f6 > ls.txt 2>lserr.txt
[root@stone ~]# cat ls.txt
f1
[root@stone ~]# cat lserr.txt
ls: cannot access f6: No such file or directory
还可以使用 2>&1
将标准输出(stdout)和标准错误(stderr)重定向到一个文件。
[root@stone ~]# ls f1 f6 > ls.txt 2>&1
[root@stone ~]# cat ls.txt
ls: cannot access f6: No such file or directory
f1
如果不想看到错误,也不想存储错误,可以将标准错误(stderr)重定向到黑洞设备 /dev/null
。
[root@stone ~]# ls f1 f6 2>/dev/null
f1
输入重定向
使用 <
以文件代替键盘作为标准输入。输入重定向并不常用,因为大多数 Linux 命令都可以接受文件名作为参数。
例如将文件 f3.txt
的内容作为标准输入,重定向给 cat
命令并输出到文件 f5.txt
。
[root@stone ~]# cat > f5.txt < f3.txt
[root@stone ~]# cat f5.txt
Hello,CentOS
上面的命令其实可以直接使用 cat
命令读取文件 f3.txt
再输出重定向给文件 f5.txt
。
[root@stone ~]# cat f3.txt > f5.txt
[root@stone ~]# cat f5.txt
Hello,CentOS
使用 <<
(称为 Here Document)指定标准输入的开始标记(一般为 EOF),完成后再输入此标记作为结束符。可以在屏幕输入字符串重定向给某个命令。
[root@stone ~]# cat > f6.txt << EOF
> Hello World,
> Hello Centos.
> EOF
[root@stone ~]# cat f6.txt
Hello World,
Hello Centos.
管道
前面使用输出重定向可以将命令的执行结果重定向到文件中,还可以使用管道符(|
)将上一个命令的标准输出作为下一个命令的标准输入,类似于数据在管道中流动,这样就可以使用多个命令对数据进行处理。
例如统计当前目录下有多少目录和文件,就可以将 ls
命令的标准输出通过管道符(|
)传递给 wc
命令作为其标准输入,即可得出计算结果。
[root@stone ~]# ls | wc -l
13
能够接收标准输入的命令就称为管道命令,除了前面的 more
,less
,head
,tail
,wc
,cut
,sort
,uniq
外,常用的管道命令还有 tr
,tee
,split
,xargs
等。
tr
使用 tr
命令对输入内容进行替换或删除。
常用选项有:
-d
:删除指定字符串。-s
:去除重复字符串。
将小写字符替换为大写字符:
[root@stone ~]# hostname | tr '[a-z]' '[A-Z]'
STONE
将 :
替换为回车:
[root@stone ~]# echo $PATH | tr ':' '\n'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin
使用 -d
选项去掉文件后缀名:
[root@stone ~]# ls *.txt | tr -d '.txt'
f3
f5
f6
lserr
ls
uniq
使用 -s
选项去掉文件中多余的空行:
[root@stone ~]# cat .bash_profile | tr -s ['\n']
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
tee
使用 tee
命令可以将标准输入分别输出到屏幕(标准输出)和文件中。
常用选项有:
-a
:将标准输入追加到文件中。
查看文件的同时将结果保存到文件 output.txt
中。
[root@stone ~]# ls f2* | tee output.txt
f2
f2_s
[root@stone ~]# cat output.txt
f2
f2_s
使用 -a
选项将结果追加到文件中。
[root@stone ~]# ls f2* | tee -a output.txt
f2
f2_s
[root@stone ~]# cat output.txt
f2
f2_s
f2
f2_s
split
使用 split
命令将一个文件分隔成多个小文件。
常用选项有:
-b
:指定每个小文件的大小。-l
:指定每个小文件的行数。
按 300k
大小分隔 /etc/services
,指定文件前缀为 services
,如果不指定,默认为 x
。
[root@stone ~]# split -b 300k /etc/services services
[root@stone ~]# ll -h servicesa*
-rw-r--r--. 1 root root 300K Jul 1 19:55 servicesaa
-rw-r--r--. 1 root root 300K Jul 1 19:55 servicesab
-rw-r--r--. 1 root root 55K Jul 1 19:55 servicesac
按 1000
行分隔 /var/log/messages
,指定文件前缀为 messages
。
[root@stone ~]# split -l 1000 /var/log/messages messages
[root@stone ~]# ll messagesa*
-rw-r--r--. 1 root root 82122 Jul 1 20:00 messagesaa
-rw-r--r--. 1 root root 85536 Jul 1 20:00 messagesab
-rw-r--r--. 1 root root 83392 Jul 1 20:00 messagesac
-rw-r--r--. 1 root root 32748 Jul 1 20:00 messagesad
xargs
使用 xargs
命令从标准输入中读取数据,然后传递给不能从标准输入中读取数据的命令,作为其参数,默认使用空格作为分隔符。
常用选项有:
-d
:指定分隔符。-n
:指定一次处理的参数个数。-p
:需要用户进行确认。-0
:使用null
作为分隔符,用于处理包含空格的文件名,一般与find
命令及其-print0
选项一起使用。-t
:执行前先输出命令-I
:替换
[root@stone ~]# find /root/ -name f3.txt | xargs ls -l
-rw-r--r--. 1 root root 13 Jun 23 16:41 /root/f3.txt
[root@stone ~]# find . -type f -name "messages*" -print0 | xargs -0 rm -f
[root@stone ~]# find . -type f -name "services*" -print0 | xargs -0 -p rm -f
rm -f ./servicesaa ./servicesab ./servicesac ?...y
为目录下所有指定文件增加一个后缀名:
[root@stone ~]# ls *.txt | xargs -t -I{} mv {} {}.bak
-
使用 -
符号来代替标准输出和标准输入,以替换命令中所需要的文件名。
[root@stone ~]# tar -cvf - d1 | tar -xvf - -C /tmp/
d1/
d1/f1
d1/f2
d1/f3
d1/
d1/f1
d1/f2
d1/f3
环境变量
与 Windows 类似,Linux 的每个用户都有环境变量。
env
使用 env
命令查看当前的环境变量。
[root@stone ~]# env
XDG_SESSION_ID=2
HOSTNAME=stone
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.92.1 61705 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=en_US.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
SSH_CONNECTION=192.168.92.1 61705 192.168.92.128 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env
其中:
PATH
:指定了命令的搜索路径,以:
分隔。 可以使用which
命令查看相关命令的路径。
[root@stone ~]# which env
/usr/bin/env
[root@stone ~]# which ls
alias ls='ls --color=auto'
/usr/bin/ls
set
使用 set
命令查看当前的 Shell 变量。
[root@stone ~]# set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
COLUMNS=104
DIRSTACK=()
EUID=0
GROUPS=()
HISTCONTROL=ignoredups
HISTFILE=/root/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/root
HOSTNAME=stone
HOSTTYPE=x86_64
ID=0
IFS=$' \t\n'
LANG=en_US.UTF-8
LESSOPEN='||/usr/bin/lesspipe.sh %s'
LINES=37
LOGNAME=root
LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:'
MACHTYPE=x86_64-redhat-linux-gnu
MAIL=/var/spool/mail/root
MAILCHECK=60
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PIPESTATUS=([0]="2")
PPID=1487
PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
PS1='[\u@\h \W]\$ '
PS2='> '
PS4='+ '
PWD=/root
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
SELINUX_USE_CURRENT_RANGE=
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=1
SSH_CLIENT='192.168.92.1 63109 22'
SSH_CONNECTION='192.168.92.1 63109 192.168.92.128 22'
SSH_TTY=/dev/pts/1
TERM=xterm
UID=0
USER=root
XDG_RUNTIME_DIR=/run/user/0
XDG_SESSION_ID=2
_=-help
colors=/root/.dircolors
其中:
PS1
:指定命令提示符\u
表示用户名\h
表示主机名\W
表示最后的目录名,主目录为~
\$
表示提示字符,如果是root
用户,提示符为#
,普通用户则为$
export
使用 export
命令创建环境变量,在当前 Shell 环境及其子程序中有效。
[root@stone ~]# export ORACLE_SID=stone
[root@stone ~]# echo $ORACLE_SID
stone
[root@stone ~]# bash
[root@stone ~]# echo $ORACLE_SID
stone
如果不使用 export
命令创建环境变量,则只在当前 Shell 环境有效。
[root@stone ~]# MYNAME=stone
[root@stone ~]# echo $MYNAME
stone
[root@stone ~]# bash
[root@stone ~]# echo $MYNAME
[root@stone ~]#
unset
使用 unset
命令清除环境变量。
[root@stone ~]# unset ORACLE_SID
[root@stone ~]# echo $ORACLE_SID
[root@stone ~]#
环境配置文件
前面使用 export
命令创建的环境变量只在当前 Shell 环境及其子程序中有效,退出当前 Shell 后就消失了,再次登录后需要重新创建。但是我们一登录到 Shell 后,执行 env
命令就可以看到很多环境变量,这是因为这些环境变量是保存在环境配置文件中的,在登录到 Shell 后,就会读取环境配置文件,以便创建这些环境变量。
环境变量文件有:
/etc/profile
:整个系统的环境配置文件,登录到 Shell 后会读取该文件。
内容如下:
[root@stone ~]# cat /etc/profile
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}
if [ -x /usr/bin/id ]; then
if [ -z "$EUID" ]; then
# ksh workaround
EUID=`/usr/bin/id -u`
UID=`/usr/bin/id -ru`
fi
USER="`/usr/bin/id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
fi
# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
fi
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
unset i
unset -f pathmunge
可以看到 /etc/profile
文件创建了 PATH
,USER
,LOGNAME
,MAIL
,HOSTNAME
,HISTSIZE
,HISTCONTROL
这几个环境变量,并读取 /etc/profile.d/*.sh
和 /etc/profile.d/sh.local
文件。
/etc/profile.d/*.sh
包含的文件有:
[root@stone ~]# ll /etc/profile.d/*.sh
-rw-r--r--. 1 root root 841 Oct 13 2020 /etc/profile.d/256term.sh
-rw-r--r--. 1 root root 201 Mar 25 2017 /etc/profile.d/colorgrep.sh
-rw-r--r--. 1 root root 1606 Aug 6 2019 /etc/profile.d/colorls.sh
-rw-r--r--. 1 root root 2703 Oct 13 2020 /etc/profile.d/lang.sh
-rw-r--r--. 1 root root 121 Jul 31 2015 /etc/profile.d/less.sh
-rw-r--r--. 1 root root 269 Dec 16 2020 /etc/profile.d/vim.sh
-rw-r--r--. 1 root root 169 Jan 28 2014 /etc/profile.d/which2.sh
/etc/profile.d/256term.sh
:创建TERM
和TERMCAP
环境变量。
内容如下:
[root@stone ~]# cat /etc/profile.d/256term.sh
# Enable 256 color capabilities for appropriate terminals
# Set this variable in your local shell config (such as ~/.bashrc)
# if you want remote xterms connecting to this system, to be sent 256 colors.
# This must be set before reading global initialization such as /etc/bashrc.
# SEND_256_COLORS_TO_REMOTE=1
# Terminals with any of the following set, support 256 colors (and are local)
local256="$COLORTERM$XTERM_VERSION$ROXTERM_ID$KONSOLE_DBUS_SESSION"
if [ -n "$local256" ] || [ -n "$SEND_256_COLORS_TO_REMOTE" ]; then
case "$TERM" in
'xterm') TERM=xterm-256color;;
'screen') TERM=screen-256color;;
'Eterm') TERM=Eterm-256color;;
esac
export TERM
if [ -n "$TERMCAP" ] && [ "$TERM" = "screen-256color" ]; then
TERMCAP=$(echo "$TERMCAP" | sed -e 's/Co#8/Co#256/g')
export TERMCAP
fi
fi
unset local256
/etc/profile.d/colorgrep.sh
:创建grep
,egrep
,fgrep
命令别名。
内容如下:
[root@stone ~]# cat /etc/profile.d/colorgrep.sh
# color-grep initialization
/usr/libexec/grepconf.sh -c || return
alias grep='grep --color=auto' 2>/dev/null
alias egrep='egrep --color=auto' 2>/dev/null
alias fgrep='fgrep --color=auto' 2>/dev/null
/etc/profile.d/colorls.sh
:创建ll
,l.
,ls
命令别名。
内容如下:
[root@stone ~]# cat /etc/profile.d/colorls.sh
# color-ls initialization
# Skip all for noninteractive shells.
[ ! -t 0 ] && return
#when USER_LS_COLORS defined do not override user LS_COLORS, but use them.
if [ -z "$USER_LS_COLORS" ]; then
alias ll='ls -l' 2>/dev/null
alias l.='ls -d .*' 2>/dev/null
INCLUDE=
COLORS=
for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM" \
"$HOME/.dir_colors" "$HOME/.dircolors"; do
[ -e "$colors" ] && COLORS="$colors" && \
INCLUDE="`/usr/bin/cat "$COLORS" | /usr/bin/grep '^INCLUDE' | /usr/bin/cut -d ' ' -f2-`" && \
break
done
[ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.$TERM" ] && \
COLORS="/etc/DIR_COLORS.$TERM"
[ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \
[ "x`/usr/bin/tty -s && /usr/bin/tput colors 2>/dev/null`" = "x256" ] && \
COLORS="/etc/DIR_COLORS.256color"
[ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS" ] && \
COLORS="/etc/DIR_COLORS"
# Existence of $COLORS already checked above.
[ -n "$COLORS" ] || return
if [ -e "$INCLUDE" ];
then
TMP="`/usr/bin/mktemp .colorlsXXX -q --tmpdir=/tmp`"
[ -z "$TMP" ] && return
/usr/bin/cat "$INCLUDE" >> $TMP
/usr/bin/grep -v '^INCLUDE' "$COLORS" >> $TMP
eval "`/usr/bin/dircolors --sh $TMP 2>/dev/null`"
/usr/bin/rm -f $TMP
else
eval "`/usr/bin/dircolors --sh $COLORS 2>/dev/null`"
fi
[ -z "$LS_COLORS" ] && return
/usr/bin/grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return
fi
unset TMP COLORS INCLUDE
alias ll='ls -l --color=auto' 2>/dev/null
alias l.='ls -d .* --color=auto' 2>/dev/null
alias ls='ls --color=auto' 2>/dev/null
/etc/profile.d/lang.sh
:创建LANG
环境变量。
内容如下:
[root@stone ~]# cat /etc/profile.d/lang.sh
# /etc/profile.d/lang.sh - set i18n stuff
sourced=0
if [ -n "$LANG" ]; then
saved_lang="$LANG"
[ -f "$HOME/.i18n" ] && . "$HOME/.i18n" && sourced=1
LANG="$saved_lang"
unset saved_lang
else
for langfile in /etc/locale.conf "$HOME/.i18n" ; do
[ -f $langfile ] && . $langfile && sourced=1
done
fi
if [ "$sourced" = 1 ]; then
[ -n "$LANG" ] && export LANG || unset LANG
[ -n "$LC_ADDRESS" ] && export LC_ADDRESS || unset LC_ADDRESS
[ -n "$LC_CTYPE" ] && export LC_CTYPE || unset LC_CTYPE
[ -n "$LC_COLLATE" ] && export LC_COLLATE || unset LC_COLLATE
[ -n "$LC_IDENTIFICATION" ] && export LC_IDENTIFICATION || unset LC_IDENTIFICATION
[ -n "$LC_MEASUREMENT" ] && export LC_MEASUREMENT || unset LC_MEASUREMENT
[ -n "$LC_MESSAGES" ] && export LC_MESSAGES || unset LC_MESSAGES
[ -n "$LC_MONETARY" ] && export LC_MONETARY || unset LC_MONETARY
[ -n "$LC_NAME" ] && export LC_NAME || unset LC_NAME
[ -n "$LC_NUMERIC" ] && export LC_NUMERIC || unset LC_NUMERIC
[ -n "$LC_PAPER" ] && export LC_PAPER || unset LC_PAPER
[ -n "$LC_TELEPHONE" ] && export LC_TELEPHONE || unset LC_TELEPHONE
[ -n "$LC_TIME" ] && export LC_TIME || unset LC_TIME
if [ -n "$LC_ALL" ]; then
if [ "$LC_ALL" != "$LANG" ]; then
export LC_ALL
else
unset LC_ALL
fi
else
unset LC_ALL
fi
[ -n "$LANGUAGE" ] && export LANGUAGE || unset LANGUAGE
[ -n "$LINGUAS" ] && export LINGUAS || unset LINGUAS
[ -n "$_XKB_CHARSET" ] && export _XKB_CHARSET || unset _XKB_CHARSET
consoletype=$CONSOLETYPE
if [ -z "$consoletype" ]; then
consoletype=$(/sbin/consoletype stdout)
fi
if [ -n "$LANG" ]; then
case $LANG in
*.utf8*|*.UTF-8*)
if [ "$TERM" = "linux" ]; then
if [ "$consoletype" = "vt" ]; then
case $LANG in
ja*) LANG=en_US.UTF-8 ;;
ko*) LANG=en_US.UTF-8 ;;
si*) LANG=en_US.UTF-8 ;;
zh*) LANG=en_US.UTF-8 ;;
ar*) LANG=en_US.UTF-8 ;;
fa*) LANG=en_US.UTF-8 ;;
he*) LANG=en_US.UTF-8 ;;
en_IN*) ;;
*_IN*) LANG=en_US.UTF-8 ;;
esac
fi
fi
;;
*)
if [ "$TERM" = "linux" ]; then
if [ "$consoletype" = "vt" ]; then
case $LANG in
ja*) LANG=en_US ;;
ko*) LANG=en_US ;;
si*) LANG=en_US ;;
zh*) LANG=en_US ;;
ar*) LANG=en_US ;;
fa*) LANG=en_US ;;
he*) LANG=en_US ;;
en_IN*) ;;
*_IN*) LANG=en_US ;;
esac
fi
fi
;;
esac
fi
unset SYSFONTACM SYSFONT consoletype
fi
unset sourced
unset langfile
这个文件会调用 /etc/locale.conf
文件,创建了 LANG
变量,指定语言(en),国家(US)及字符集(UTF-8),内容如下:
[root@stone ~]# cat /etc/locale.conf
LANG="en_US.UTF-8"
/etc/profile.d/less.sh
:创建LESSOPEN
环境变量,用于指定less
命令的输入处理器。
内容如下:
[root@stone ~]# cat /etc/profile.d/less.sh
# less initialization script (sh)
[ -x /usr/bin/lesspipe.sh ] && export LESSOPEN="${LESSOPEN-||/usr/bin/lesspipe.sh %s}"
/etc/profile.d/vim.sh
:创建vi
命令别名。
内容如下:
[root@stone ~]# cat /etc/profile.d/vim.sh
if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n "$ZSH_VERSION" ]; then
[ -x /usr/bin/id ] || return
ID=`/usr/bin/id -u`
[ -n "$ID" -a "$ID" -le 200 ] && return
# for bash and zsh, only if no alias is already set
alias vi >/dev/null 2>&1 || alias vi=vim
fi
/etc/profile.d/which2.sh
:创建which
命令别名。
内容如下:
[root@stone ~]# cat /etc/profile.d/which2.sh
# Initialization script for bash and sh
# export AFS if you are in AFS environment
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
/etc/profile.d/sh.local
:可以将自定义的环境变量添加到此文件,作用于所有用户。
内容如下:
[root@stone ~]# cat /etc/profile.d/sh.local
#Add any required envvar overrides to this file, it is sourced from /etc/profile
~/.bash_profile
:用户的环境配置文件,只作用于当前用户。
内容如下:
[root@stone ~]# cat ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
可以看到会判断是否有 ~/.bashrc
文件,如果有就读取该文件。然后为 PATH
环境变量增加 $HOME/bin
这个目录。可以在此文件中添加特定于当前用户的环境变量。
~/.bashrc
:创建rm
,cp
和mv
命令别名。然后判断是否有/etc/bashrc
,如果有就读取该文件。
内容如下:
[root@stone ~]# cat ~/.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
/etc/bashrc
:指定$PS1
,umask
以及读取/etc/profile.d/*.sh
。
[root@stone ~]# cat /etc/bashrc
# /etc/bashrc
# System wide functions and aliases
# Environment stuff goes in /etc/profile
# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.
# are we an interactive shell?
if [ "$PS1" ]; then
if [ -z "$PROMPT_COMMAND" ]; then
case $TERM in
xterm*|vte*)
if [ -e /etc/sysconfig/bash-prompt-xterm ]; then
PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
elif [ "${VTE_VERSION:-0}" -ge 3405 ]; then
PROMPT_COMMAND="__vte_prompt_command"
else
PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
fi
;;
screen*)
if [ -e /etc/sysconfig/bash-prompt-screen ]; then
PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen
else
PROMPT_COMMAND='printf "\033k%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
fi
;;
*)
[ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default
;;
esac
fi
# Turn on parallel history
shopt -s histappend
history -a
# Turn on checkwinsize
shopt -s checkwinsize
[ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "
# You might want to have e.g. tty in prompt (e.g. more virtual machines)
# and console windows
# If you want to do so, just add e.g.
# if [ "$PS1" ]; then
# PS1="[\u@\h:\l \W]\\$ "
# fi
# to your custom modification shell script in /etc/profile.d/ directory
fi
if ! shopt -q login_shell ; then # We're not a login shell
# Need to redefine pathmunge, it get's undefined at the end of /etc/profile
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}
# By default, we want umask to get set. This sets it for non-login shell.
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
SHELL=/bin/bash
# Only display echos from profile.d scripts if we are no login shell
# and interactive - otherwise just process them to set envvars
for i in /etc/profile.d/*.sh; do
if [ -r "$i" ]; then
if [ "$PS1" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
unset i
unset -f pathmunge
fi
# vim:ts=4:sw=4
~/.bash_logout
:指定退出 Shell 时执行的操作。
[root@stone ~]# cat ~/.bash_logout
# ~/.bash_logout
在使用中,可以将 Shell 分为:
- Login Shell:登录后获取的 Shell,例如使用终端登录或者执行
su - username
命令获取的 Shell,此时会读取/etc/profile
和~/.bash_profile
文件。
- No-Login Shell:无需登录获取的 Shell,例如执行
bash
或者su username
命令获取的 Shell,此时会读取~/.bashrc
文件。
source
使用 source
命令或者 .
(点)读取环境配置文件。
如果修改了环境配置文件,比如在 ~/.bash_profile
文件中增加了环境变量,使用 source
命令读取该文件后,即可让增加的环境变量生效。
[root@stone ~]# echo "export DISPLAY=192.168.92.128:0.0" >> ~/.bash_profile
[root@stone ~]# echo $DISPLAY
[root@stone ~]# source ~/.bash_profile
[root@stone ~]# echo $DISPLAY
192.168.92.128:0.0
命令别名
可以为带某个选项的命令或者一组命令指定一个别名,方便使用。
alias
使用 alias
命令查看和指定命令别名。
查看当前所有命令别名:
[root@stone ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --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@stone ~]# alias cls='clear'
[root@stone ~]# alias cls
alias cls='clear'
注意,此时创建的命令别名只在当前会话有效,断开该会话后,该命令别名消失。可以将 alias cls='clear'
加入到 .bashrc
或者 .bash_profile
文件中,永久生效。
unalias
使用 unalias
命令取消命令别名。
[root@stone ~]# unalias cls
如果不想取消命令别名,但有时又需要使用原始命令,则可以使用 \
。
[root@stone ~]# \rm uniq.txt.gz
此时就不会使用 rm -i
命令,使用 rm
命令直接删除,慎用。
type
使用 type
命令查看命令的类型。
常用选项有:
-a
:列出指定命令的所有路径,包括别名。-t
:列出指定命令的类型,有:file
:表示外部命令alias
:表示别名builtin
:表示 Bash 自带命令
[root@stone ~]# type -a ls
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls
[root@stone ~]# type -t -a ls
alias
file
[root@stone ~]# type -a echo
echo is a shell builtin
echo is /usr/bin/echo
可以看到 ls
命令有 2 个,那么发出 ls
命令的时候,使用哪一个命令呢。实际上就是按照 type
或者 which
命令的输出顺序来决定的。
命令的选择顺序具体如下:
- 以相对/绝对路径执行命令,例如
/usr/bin/ls
。 - 命令的别名。
- Bash 自带的命令。
- 通过
PATH
环境变量找到的第一个命令。
命令历史记录
命令历史记录的操作过程如下:
- 登录到 Shell 后,会从
~/.bash_history
文件中读取命令历史记录到缓冲区。 - 在操作时,会将执行的命令记录到缓冲区。
- 在退出 Shell 时,会将缓冲区的命令保存到
~/.bash_history
文件中。
涉及到的环境变量如下:
HISTSIZE
:控制缓冲区历史记录的最大个数,默认为 1000,设置为 0 表示禁用历史记录。HISTFILE
:指定历史记录文件,默认为~/.bash_history
。HISTFILESIZE
:控制历史记录文件中的最大个数,默认为 1000,设置为 0 表示禁用历史记录。HISTIGNORE
:设置哪些命令不记录到历史记录。HISTTIMEFORMAT
:设置历史记录显示的时间格式,默认不显示时间,可以设置为export HISTTIMEFORMAT="%F %T "
显示时间戳。HISTCONTROL
:扩展的控制选项,可以为:ignorespace
:忽略空格开头的命令。ignoredups
:忽略连续重复命令,默认值。ignoreboth
:表示上述两个参数都设置。
history
除了可以使用方向键 ↑
或者 ↓
浏览已执行命令的历史记录,还使用 history
命令查看已执行命令的历史记录。
常用选项有:
n
:数字,表示列出最近的n
条历史记录。
[root@stone ~]# history 2
2 ls f1
3 history 2
-c
:清除缓冲区所有命令历史记录。
[root@stone ~]# history -c
[root@stone ~]# history
1 history
-d
:删除某条历史记录。
[root@stone ~]# history
1 history
2 ls
3 history
[root@stone ~]# history -d 2
[root@stone ~]# history
1 history
2 history
3 history -d 2
4 history
-a
:将登录到 Shell 后执行的命令写入到~/.bash_history
文件中。
[root@stone ~]# history -a
[root@stone ~]# tail -5 ~/.bash_history
history
history
history -d 2
history
history -a
-r
:读取~/.bash_history
文件内容到缓冲区。
[root@stone ~]# history -r
!
使用 !
(叹号)来快速执行某个历史命令。
- 使用
! + 数字
执行某个编号的历史命令。
[root@stone ~]# history
1 exit
2 ls
3 alias
4 history
[root@stone ~]# !3
alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --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@stone ~]# !!
- 使用
! + 命令开头字符串
执行最近以某个字符串开头的命令。
[root@stone ~]# !al
- 使用
! + 命令开头字符串 + :p
列出最近以某个字符串开头的命令,然后使用方向键↑
选择执行。
[root@stone ~]# !al:p
alias
[root@stone ~]# alias
- 使用
! + ? + 命令包含字符串
执行最近包含某个字符串的命令。
[root@stone ~]# !?lia
还可以按下 Ctrl + R
后,键入命令的部分字符,自动在历史文件中查询并显示最近一条匹配的结果,按下回车执行。
正则
正则表达式是一种用于匹配和操作字符串的工具,它可以用来检查字符串是否符合特定的模式,或者从字符串中提取满足特定模式的子串。正则表达式通常由一些特殊字符和普通字符组成,这些字符组合在一起形成一个模式,用于描述要匹配的字符串的特征和结构。在编程和文本处理中,正则表达式是一个非常强大和常用的工具。
简而言之,正则表达式就是使用有限的字符,来匹配无限字符。
语法
正则表达式可以分为:
- 元字符,包括
. ? * + { } ^ $ [ ] - ( ) | \
。
字符 | 含义 |
---|---|
. | 匹配任意一个字符 |
? | 匹配前面的子表达式 0 或者 1 次 |
* | 匹配前面的子表达式 0 或者多次 |
+ | 匹配前面的子表达式 1 或者多次 |
{n} | 匹配前面的子表达式 n 次 |
{n,} | 匹配前面的子表达式至少 n 次 |
{n,m} | 匹配前面的子表达式至少 n 次,至多 m 次 |
{,m} | 匹配前面的子表达式至多 m 次 |
^ | 匹配文本行开头 |
$ | 匹配文本行结尾 |
[xyz] | 匹配 xyz 中的任一字符 |
[^xyz] | 匹配 xyz 之外的任一字符 |
[a-z] | 匹配 a 到 z 的任一字符 |
[^a-z] | 匹配 a 到 z 之外的任一字符 |
abc|xyz | 匹配 abc 或者 xyz |
(xyz) | 匹配 xyz 字符串 |
(abc|xyz) | 匹配 abc 或者 xyz |
\b | 匹配一个单词边界,也就是单词和空格间的位置。 |
\B | 匹配一个非单词边界 |
\d | 匹配一个数字,等价于 [0-9] |
\D | 匹配一个非数字,等价于 [^0-9] |
\w | 匹配一个字母、数字、下划线,等价于 [A-Za-z0-9_] |
\W | 匹配一个非字母、数字、下划线,等价于 [^A-Za-z0-9_] |
\< | 匹配单词开头的空字符串 |
\> | 匹配单词末尾的空字符串 |
- 预定义字符
字符 | 含义 |
---|---|
[:alnum:] | 字母数字字符。在 ASCII 中,等价于 [A-Za-z0-9] |
[:word:] | 与 [:alnum:] 相同,但增加了下划线字符 |
[:alpha:] | 字母字符。在 ASCII 中,等价于 [A-Za-z] |
[:blank:] | 包含空格和 Tab 字符 |
[:cntrl:] | ASCII 的控制码。包含了 0 到 31,和 127 的 ASCII 字符 |
[:digit:] | 数字 0 到 9 |
[:graph:] | 可视字符。在 ASCII 中,它包含 33 到 126 的字符 |
[:lower:] | 小写字母。 |
[:punct:] | 标点符号字符。 |
[:print:] | 可打印的字符。等于 [:graph:] 中的所有字符,再加上空格字符。 |
[:space:] | 空白字符,包括空格,Tab,回车,换行,Vertical Tab, 和 Form Feed。在 ASCII 中, 等价于 [ \t\r\n\v\f] |
[:upper:] | 大写字母。 |
[:xdigit:] | 用来表示十六进制数字的字符。在 ASCII 中,等价于 [0-9A-Fa-f] |
命令
grep
使用 grep
(Globally search a Regular Expression and Print)命令以及正则表达式查找文件内容。
常用选项有:
-i
:忽略大小写。-v
:反向查找,显示不匹配的行。-n
:显示匹配行的行号。-r
:递归查找目录下的文件。-l
:显示匹配的文件名。-c
:显示匹配的行数。-w
:需要完全匹配单词。-B NUM
:显示匹配的行及其前面NUM
行。-A NUM
:显示匹配的行及其后面NUM
行。-C NUM
:显示匹配的行及其前后NUM
行。-E
:使用扩展的正则表达式,等价于egrep
。
忽略大小写查找,结果显示行号:
[root@stone ~]# grep -in path .bash_profile
10:PATH=$PATH:$HOME/bin
12:export PATH
不显示文本中的空行:
[root@stone ~]# grep -v ^$ .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
export DISPLAY=192.168.92.128:0.0
不显示文本中的空行及注释:
[root@stone ~]# grep -v ^$ .bash_profile | grep -v ^#
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
PATH=$PATH:$HOME/bin
export PATH
export DISPLAY=192.168.92.128:0.0
查找 PATH
关键字所在的行及其前后 3 行:
[root@stone ~]# grep -C 3 PATH .bash_profile
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
export DISPLAY=192.168.92.129:0.0
sed
使用 sed
(Stream EDitor)命令以及正则表达式处理文件内容。
常用选项有:
-n
:只输出被处理的行。-i
:修改原文件。-r
:使用扩展正则表达式。
处理文件内容通过动作实现,语法为:[n1[,n2]]动作
。其中 n1
,n2
表示行数。动作有:
a
:新增数据到下一行。c
:替换指定行。d
:删除指定行。i
:插入数据到上一行。p
:打印指定行。s
:替换指定行的某些数据。格式为's/原字符串/新字符串/g'
。
在指定行后面增加一行:
[root@stone ~]# nl -ba .bash_profile | sed '12a export ORACLE_SID=stone'
12 export PATH
export ORACLE_SID=stone
13 export DISPLAY=192.168.92.128:0.0
替换指定行:
[root@stone ~]# nl -ba .bash_profile | sed '13c export ORACLE_SID=stone'
export ORACLE_SID=stone
删除指定行:
[root@stone ~]# nl -ba .bash_profile | sed '13d'
删除指定行到末尾所有行:
[root@stone ~]# sed '13,$d' .bash_profile
删除最后一行:
[root@stone ~]# sed '$d' .bash_profile
去掉空行:
[root@stone ~]# sed '/^$/d' .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
export DISPLAY=192.168.92.128:0.0
在指定行前面插入一行:
[root@stone ~]# nl -ba .bash_profile | sed '13i export ORACLE_SID=stone'
export ORACLE_SID=stone
13 export DISPLAY=192.168.92.128:0.0
打印 4-6 行:
[root@stone ~]# sed -n '4,6p' .bash_profile
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
打印从指定字符串的行到尾行:
[root@stone ~]# sed -n '/PATH/,$p' .bash_profile
PATH=$PATH:$HOME/bin
export PATH
export DISPLAY=192.168.92.129:0.0
替换指定数据,可以使用正则表达式进行匹配。
[root@stone ~]# sed 's/128/129/g' .bash_profile
export DISPLAY=192.168.92.129:0.0
使用 &
引用匹配的字符串:
[root@stone ~]# echo Hello World | sed 's/\w\+/[&]/g'
[Hello] [World]
以上动作都不会修改原文件,可以使用 -i
选项修改原文件:
[root@stone ~]# sed -i 's/128/129/g' .bash_profile
[root@stone ~]# tail -1 .bash_profile
export DISPLAY=192.168.92.129:0.0
printf
使用 printf
命令格式化文件内容输出。
语法:
printf FORMAT [ARGUMENT]...
其中 FORMAT
:
%[-]ns
:s
表示字符,n
表示字符宽度,不足会以空格填充,-
表示左对齐,否则为右对齐。%ni
:i
表示整数,n
表示位数。%N.nf
:f
表示小数,N
表示整数位数,n
表示小数位数。
特殊字符有:
字符 | 含义 |
---|---|
" | double quote |
\ | backslash |
\a | alert (BEL) |
\b | backspace |
\c | produce no further output |
\e | escape |
\f | form feed |
\n | new line |
\r | carriage return |
\t | horizontal tab |
\v | vertical tab |
例如对于以下文本:
[root@stone ~]# cat printf.txt
Name Chinese English Math Average
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
格式化输出:
[root@stone ~]# printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt | grep -v Name)
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
awk
awk
是一种编程语言,用于在 Linux 下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是 Linux 下的一个强大编程工具。它可在命令行中使用,但更多是作为脚本来使用。awk
有3个不同版本: awk
、nawk
和 gawk
,未作特别说明,一般指 gawk
。
语法
awk [-F field-separator] 'program' input-file(s)
其中,program
是真正 awk
命令,必须包含在单引号中,格式为:
'BEGIN { actions }
pattern1 { actions }
............
patternN { actions }
END { actions }'
[-F field-separator]
是可选的, input-file(s)
是待处理的文件。在 awk
中,文件的每一行中,由字段分隔符分开的每一项称为一个域。通常,在不指定 [-F field-separator]
的情况下,默认的字段分隔符是空格。
运行过程:
- 如果 BEGIN 存在,执行它指定的 actions。
- 从输入文件中读取一行,称为一条输入记录。
- 将读入的记录分割成字段,将第 1 个字段放入变量 $1 中,第 2 个字段放入 $2,以此类推。$0 表示整条记录。
- 把当前输入记录依次与每一个 pattern 比较,看是否匹配,如果相匹配,就执行对应的 actions。如果不匹配,就跳过对应的 actions,直到比较完所有的 pattern。如果没有指定 actions,则使用默认的 actions,即打印当前输入记录
{print $0}
。 - 读取输入的下一行,继续重复步骤 3 和 4。
- 读完所有的输入行后,如果存在 END,就执行相应的 actions。
变量
在 program
可以使用以下变量:
变量名称 | 描述 |
---|---|
$n | 当前记录的第 n 个字段,字段间由 FS 分隔。(列内容) |
$0 | 完整的输入记录。(行内容) |
NF | 当前记录中的字段数。(列数) |
NR | 当前记录数。(行数) |
FNR | 同 NR,但相对于当前文件。 |
FS | 字段分隔符(默认是任何空格)。(输入列分隔符) |
RS | 记录分隔符(默认是一个换行符)。(输入行分隔符) |
OFS | 输出字段分隔符(默认值是一个空格)。(输入列分隔符) |
ORS | 输出记录分隔符(默认值是一个换行符)。(输出行分隔符) |
ARGC | 命令行参数的数目。 |
ARGIND | 命令行中当前文件的位置(从 0 开始算)。 |
ARGV | 包含命令行参数的数组。 |
CONVFMT | 数字转换格式(默认值为 %.6g ) |
ENVIRON | 环境变量关联数组。 |
ERRNO | 最后一个系统错误的描述。 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔)。 |
FILENAME | 当前文件名。 |
IGNORECASE | 如果为真,则进行忽略大小写的匹配。 |
OFMT | 数字的输出格式(默认值是 %.6g )。 |
RLENGTH | 由 match 函数所匹配的字符串的长度。 |
RSTART | 由 match 函数所匹配的字符串的第一个位置。 |
SUBSEP | 数组下标分隔符(默认值是 \034 )。 |
运算符
运算符 | 描述 |
---|---|
= += -= *= /= %= ^= **= | 赋值 |
?: | C条件表达式 |
|| | 逻辑或 |
&& | 逻辑与 |
! | 逻辑非 |
~ !~ | 匹配正则表达式和不匹配正则表达式 |
< <= > >= != == | 关系运算符 |
空格 | 字符串连接 |
+ - | 加,减 |
* / & | 乘,除与求余 |
^ ** | 求幂 |
++ -- | 增加或减少,作为前缀或后缀 |
$ | 域引用 |
in | 数组成员 |
模式
名称 | 含义 |
---|---|
/正则表达式/ | 使用正则表达式匹配记录 |
关系表达式 | 使用关系运算符进行操作 |
模式匹配表达式 | 使用运算符 ~ (匹配)和 !~ (不匹配) |
BEGIN | 指定在第一条输入记录被处理之前所发生的动作,可选 |
Pattern1,pattern2 | 指定行的范围,该语法不包括 BEGIN 和 END 模式 |
END | 指定在最后一条输入记录被处理之后发生的动作,可选 |
示例
创建待处理的文件:
[root@stone ~]# df -h > dflog
[root@stone ~]# cat dflog
Filesystem Size Used Avail Use% Mounted on
devtmpfs 898M 0 898M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.5M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.5G 16G 9% /
/dev/sda1 1014M 150M 865M 15% /boot
tmpfs 182M 0 182M 0% /run/user/0
选择指定的行:
[root@stone ~]# awk 'NR==2' dflog
devtmpfs 898M 0 898M 0% /dev
[root@stone ~]# awk '/shm/,/boot/' dflog
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.5M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.5G 16G 9% /
/dev/sda1 1014M 150M 865M 15% /boot
[root@stone ~]# df | awk '$2>1000000'
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 17811456 1551392 16260064 9% /
/dev/sda1 1038336 153572 884764 15% /boot
输出指定列:
[root@stone ~]# awk '{print $5}' dflog
Use%
0%
0%
2%
0%
9%
15%
0%
输出指定行指定列:
[root@stone ~]# awk 'NR==7{print $5}' dflog
15%
[root@stone ~]# awk 'NR==6,NR==7{print $1}' dflog
/dev/mapper/centos-root
/dev/sda1
正则匹配:
[root@stone ~]# awk '/\/dev\/sda1/' dflog
/dev/sda1 1014M 150M 865M 15% /boot
[root@stone ~]# awk '/^(\/dev\/sda|Filesystem)/' dflog
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 1014M 150M 865M 15% /boot
[root@stone ~]# sed 's/%//g' dflog | awk '/^\/dev\/sda/{if ($5>10) print $1}'
/dev/sda1
[root@stone ~]# sed 's/%//g' dflog | awk '/^\/dev\/sda/ && $5>10'
/dev/sda1 1014M 150M 865M 15 /boot
[root@stone ~]# sed 's/%//g' dflog | awk '/^\/dev\/sda/{print($5>10? $1" error":$1" ok")}'
/dev/sda1 error
[root@stone ~]# awk '$6~/\/boot/{print $1}' dflog
/dev/sda1
[root@stone ~]# awk '$1!~/tmpfs/{print $1}' dflog
Filesystem
/dev/mapper/centos-root
/dev/sda1
使用 BEGIN 初始化变量:
[root@stone ~]# awk 'BEGIN{FS=":"}$3<5{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
也可以使用 -F
指定分隔符:
[root@stone ~]# awk -F ':' '$3<5{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
指定输出的分隔符:
[root@stone ~]# awk 'BEGIN{OFS=":"}NR==1,NR==3{print $1,$5,$6}' dflog
Filesystem:Use%:Mounted
devtmpfs:0%:/dev
tmpfs:0%:/dev/shm
如果 program
中的内容很多,可以写在一个 awk
脚本里面,使用 -f
选项指定脚本:
原始数据:
[root@stone ~]# cat score.txt
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62
awk
脚本:
[root@stone ~]# cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf "---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf "---------------------------------------------\n"
printf " TOTAL:%10d %8d %8d \n", math, english, computer
printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}
执行:
[root@stone ~]# awk -f cal.awk score.txt
NAME NO. MATH ENGLISH COMPUTER TOTAL
---------------------------------------------
Marry 2143 78 84 77 239
Jack 2321 66 78 45 189
Tom 2122 48 77 71 196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
---------------------------------------------
TOTAL: 319 393 350
AVERAGE: 63.80 78.60 70.00
diff
使用 diff
命令比较两个文本的内容。
常用选项有:
-i
:忽略大小写。-q
:只说明文件是否相同。-y
:并排比较。-W
:并排比较时指定宽度(默认 130)。-u
:以合并的方式显示不同。-c
:显示两个文本内容及不同之处。
例如有以下两个文件:
[root@stone ~]# cat a.txt
Hello
world
hello
CentOs
[root@stone ~]# cat b.txt
world
Hello
CentOs
Bye
只显示两个文件是否相同:
[root@stone ~]# diff -iq a.txt b.txt
Files a.txt and b.txt differ
显式两个文件不同之处:
[root@stone ~]# diff a.txt b.txt
1c1
< Hello
---
>
3c3
< hello
---
> Hello
4a5
> Bye
并排比较两个文件:
[root@stone ~]# diff -iy -W 30 a.txt b.txt
Hello |
world world
hello Hello
CentOs CentOs
> Bye
其中:
|
:表示这一行内容不同。<
:前面文件比后面文件多一行。>
:后面文件比前面文件多一行。
以合并方式输出文件不同:
[root@stone ~]# diff -u a.txt b.txt
--- a.txt 2023-07-15 20:22:07.429377286 +0800
+++ b.txt 2023-07-15 20:22:52.622380020 +0800
@@ -1,4 +1,5 @@
-Hello
+
world
-hello
+Hello
CentOs
+Bye
显示两个文本内容及不同之处:
[root@stone ~]# diff -c a.txt b.txt
*** a.txt 2023-07-15 20:22:07.429377286 +0800
--- b.txt 2023-07-15 20:22:52.622380020 +0800
***************
*** 1,4 ****
! Hello
world
! hello
CentOs
--- 1,5 ----
!
world
! Hello
CentOs
+ Bye
用户
在前面的 chmod 命令中提到文件和目录的所有者可能是用户(user)、组(group)或者其他人(others)。本节讲述如何管理用户和组。
文件
在Linux中,每个用户都有一个唯一的用户 ID(UID)和一个所属的组 ID(GID)。用户可以属于一个或多个组,一个组可以包含一个或者多个用户,这样就可以共享文件和目录的访问权限。
与用户相关的文件有:
/etc/passwd
:每一行表示一个用户账号信息。
[root@stone ~]# cat /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
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
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
每行的语法格式如下表:
用户名 | 密码 | UID | GID | 备注信息 | 主目录 | 登陆 Shell |
---|---|---|---|---|---|---|
root | x | 0 | 0 | root | /root | /bin/bash |
postfix | x | 89 | 89 | /var/spool/postfix | /sbin/nologin |
每个字段的意义如下表:
字段 | 内容 | 含义 |
---|---|---|
1 | 用户名 | 表示登陆用户的用户名,root 用户为默认管理员,可以进行任何操作 |
2 | 密码 | 表示该用户的登陆密码,在 /etc/passwd 登陆密码都为 x ,实际密码加密保存在 /etc/shadow 中 |
3 | UID | 用户 ID,Linux 为每个用户分配一个整数 ID,系统管理员 root 的 ID 为 0,1~499 为系统 ID,500~65535 为用户 ID |
4 | GID | 组 ID,Linux 为每一组分配一个整数 ID |
5 | 备注信息 | 一般无需设置 |
6 | 主目录 | 用户登陆后的默认目录 |
7 | 登陆Shell | 用户登陆时的默认 Shell,如果为 /sbin/nologin 表示不允许登录。 |
/etc/shadow
:每一行表示一个用户账号密码信息。
[root@stone ~]# cat /etc/shadow
root:$6$YJuEqeT9BxW9vX0a$ArIhJ49lVoYkqfojs5Pi2yj3TcmRhVyqoqBqLynrhFqGVabkWe238YogtSTJPSOjdrBcLx83QyzoT8AIe/AsM/::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::
sync:*:18353:0:99999:7:::
shutdown:*:18353:0:99999:7:::
halt:*:18353:0:99999:7:::
mail:*:18353:0:99999:7:::
operator:*:18353:0:99999:7:::
games:*:18353:0:99999:7:::
ftp:*:18353:0:99999:7:::
nobody:*:18353:0:99999:7:::
systemd-network:!!:19530::::::
dbus:!!:19530::::::
polkitd:!!:19530::::::
sshd:!!:19530::::::
postfix:!!:19530::::::
每个字段的意义如下表:
字段 | 内容 | 含义 |
---|---|---|
1 | 用户名 | 表示登陆用户的用户名 |
2 | 密码 | 表示加密的密码 |
3 | 密码修改日期 | 表示密码修改日期与 1970-01-01 之间的天数 |
4 | 密码冻结天数 | 表示密码修改后再修改需要等待的天数 |
5 | 密码有效天数 | 表示密码修改后可以使用的天数 |
6 | 密码警告天数 | 表示密码在有效天数到来之前向用户发出警告的天数 |
7 | 密码宽限天数 | 表示密码在有效天数到来之后可以继续使用的天数 |
8 | 账号失效日期 | 表示账号失效日期与 1970-01-01 之间的天数 |
与组相关的文件有:
/etc/group
:每一行表示一个用户组信息。
[root@stone ~]# cat /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mem:x:8:
kmem:x:9:
wheel:x:10:
cdrom:x:11:
mail:x:12:postfix
man:x:15:
dialout:x:18:
floppy:x:19:
games:x:20:
tape:x:33:
video:x:39:
ftp:x:50:
lock:x:54:
audio:x:63:
nobody:x:99:
users:x:100:
utmp:x:22:
utempter:x:35:
input:x:999:
systemd-journal:x:190:
systemd-network:x:192:
dbus:x:81:
polkitd:x:998:
ssh_keys:x:997:
sshd:x:74:
postdrop:x:90:
postfix:x:89:
每行的语法格式如下表:
用户组名称 | 组密码 | GID | 组内成员 |
---|---|---|---|
root | x | 0 |
每个字段的意义如下表:
字段 | 内容 | 含义 |
---|---|---|
1 | 用户组名称 | 用户组名称 |
2 | 组密码 | 一般无需设置,在 /etc/group 中登陆密码都为 x ,实际密码加密保存在 /etc/gshadow 中 |
3 | GID | 组 ID,Linux 为每一组分配一个整数 ID,对应 /etc/passwd 中的 GID |
4 | 组内成员 | 组成员列表,使用逗号隔开 |
命令
id
使用 id
命令查看用户的 UID,GID 以及用户所属组。
常用选项有:
-u
:只显示 UID-g
:只显式 GID-G
:显示所属组 ID
[root@stone ~]# id root
uid=0(root) gid=0(root) groups=0(root)
[root@stone ~]# id -u
0
[root@stone ~]# id -g
0
[root@stone ~]# id -G
0
groupadd
使用 groupadd
命令创建组。
常用选项有:
-g GID
:指定 GID,/etc/group
中第 3 字段内容-r
:创建一个系统组,GID 在/etc/login.defs
文件定义的 SYS_GID_MIN(201) 和 SYS_GID_MAX(999) 之间
[root@stone ~]# groupadd dba
[root@stone ~]# tail -1 /etc/group
dba:x:1001:
创建一个系统组:
[root@stone ~]# groupadd -r httpd
[root@stone ~]# tail -1 /etc/group
httpd:x:996:
groupmod
使用 groupmod
命令修改组。
常用选项有:
-n NEW_GROUP
:修改组名,/etc/group
中第 1 字段内容-g GID
:修改 GID,/etc/group
中第 3 字段内容,一般不要修改 GID
[root@stone ~]# groupmod -n apache httpd
[root@stone ~]# grep apache /etc/group
apache:x:996:
groupdel
使用 groupdel
命令删除组。
常用选项有:
-f
:强制删除用户主组。
[root@stone ~]# groupdel apache
useradd
使用 useradd
命令创建用户。
常用选项有:
-u UID
:指定 UID,/etc/passwd
中第 3 字段内容-g GID
:指定 GID,/etc/passwd
中第 4 字段内容-c comment
:添加备注,/etc/passwd
中第 5 字段内容-d homedir
:设置用户主目录,/etc/passwd
中第 6 字段内容-s loginshell
:设置登录 Shell,/etc/passwd
中第 7 字段内容-G group1,group2
:设置次要组,修改/etc/group
中相关组的第 4 字段
不使用命令选项直接增加用户,由系统指定 UID 和 GID,并创建主目录,设置登录 Shell 为 /bin/bash
:
[root@stone ~]# useradd stone
[root@stone ~]# grep stone /etc/passwd /etc/shadow /etc/group
/etc/passwd:stone:x:1000:1000::/home/stone:/bin/bash
/etc/shadow:stone:!!:19553:0:99999:7:::
/etc/group:stone:x:1000:
[root@stone ~]# id stone
uid=1000(stone) gid=1000(stone) groups=1000(stone)
[root@stone ~]# tail -1 /etc/group
stone:x:1000:
可以看到使用 useradd username
来创建用户时,系统默认会处理以下几个项目:
- 在
/etc/passwd
里面创建一行与用户相关的数据 - 在
/etc/shadow
里面将此用户密码相关参数填入,但是尚未有密码 - 在
/etc/group
里面加入一个与用户名称一模一样的组名 - 在
/home
目录下创建一个与用户同名的目录作为主目录,且权限为 700
创建用户后,会自动在该用户的主目录 /home/stone
下生成 .bash_logout
,.bash_profile
和 .bashrc
这三个文件:
[root@stone ~]# ls -a /home/stone/
. .. .bash_logout .bash_profile .bashrc
以上操作参考的是创建用户的默认配置,使用 -D
选项可以查看创建用户时的默认配置:
[root@stone ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
以上配置来自于文件 /etc/default/useradd
:
[root@stone ~]# cat /etc/default/useradd
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
其中:
GROUP=100
:表示新创建用户的初始组 GID 为 100,这个配置不适用于 RHEL,CentOS 发行版。HOME=/home
:表示新创建用户的主目录在/home
目录下。INACTIVE=-1
:表示密码在有效天数到来之后可以继续使用的天数,设置/etc/shadow
第 7 个字段,指定-1
表示密码永不失效。EXPIRE=
:表示账号失效日期与 1970-01-01 之间的天数,设置/etc/shadow
第 8 个字段,一般不指定。SHELL=/bin/bash
:表示用户登陆时的默认 Shell,设置/etc/passwd
第 7 个字段。SKEL=/etc/skel
:表示会将此目录下的文件拷贝到用户主目录。此目录下的文件有:
[root@stone ~]# ls -a /etc/skel/
. .. .bash_logout .bash_profile .bashrc
CREATE_MAIL_SPOOL=yes
:表示在/var/spool/mail/
目录下为新用户创建邮箱目录。
[root@stone ~]# ll /var/spool/mail/stone
-rw-rw----. 1 stone mail 0 Jul 15 22:47 /var/spool/mail/stone
那这个邮箱目录又是在哪里指定的呢,就是 /etc/login.defs
这个文件,其还指定了创建用户时的其他配置:
[root@stone ~]# cat /etc/login.defs
#
# Please note that the parameters in this configuration file control the
# behavior of the tools from the shadow-utils component. None of these
# tools uses the PAM mechanism, and the utilities that use PAM (such as the
# passwd command) should therefore be configured elsewhere. Refer to
# /etc/pam.d/system-auth for more information.
#
# *REQUIRED*
# Directory where mailboxes reside, _or_ name of file, relative to the
# home directory. If you _do_ define both, MAIL_DIR takes precedence.
# QMAIL_DIR is for Qmail
#
#QMAIL_DIR Maildir
MAIL_DIR /var/spool/mail
#MAIL_FILE .mail
# Password aging controls:
#
# PASS_MAX_DAYS Maximum number of days a password may be used.
# PASS_MIN_DAYS Minimum number of days allowed between password changes.
# PASS_MIN_LEN Minimum acceptable password length.
# PASS_WARN_AGE Number of days warning given before a password expires.
#
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7
#
# Min/max values for automatic uid selection in useradd
#
UID_MIN 1000
UID_MAX 60000
# System accounts
SYS_UID_MIN 201
SYS_UID_MAX 999
#
# Min/max values for automatic gid selection in groupadd
#
GID_MIN 1000
GID_MAX 60000
# System accounts
SYS_GID_MIN 201
SYS_GID_MAX 999
#
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#
#USERDEL_CMD /usr/sbin/userdel_local
#
# If useradd should create home directories for users by default
# On RH systems, we do. This option is overridden with the -m flag on
# useradd command line.
#
CREATE_HOME yes
# The permission mask is initialized to this value. If not specified,
# the permission mask will be initialized to 022.
UMASK 077
# This enables userdel to remove user groups if no members exist.
#
USERGROUPS_ENAB yes
# Use SHA512 to encrypt password.
ENCRYPT_METHOD SHA512
其中:
MAIL_DIR
:表示邮箱目录。PASS_MAX_DAYS
:密码修改后可以使用的天数,默认为 9999,设置/etc/passwd
第 5 个字段。PASS_MIN_DAYS
:密码修改后再修改需要等待的天数,默认为 0,表示可以随时修改密码,设置/etc/passwd
第 4 个字段。PASS_MIN_LEN
:密码最短长度。PASS_WARN_AGE
:密码在有效天数到来之前向用户发出警告的天数,默认为 7,设置/etc/passwd
第 7 个字段。UID_MIN
:普通用户最小 UID,默认为 1000。UID_MAX
:普通用户最大 UID,默认为 60000。SYS_UID_MIN
:系统用户最小 UID,默认为 201。SYS_UID_MAX
:系统用户最大 UID,默认为 999。GID_MIN
:普通用户最小 GID,默认为 1000。GID_MAX
:普通用户最大 GID,默认为 60000。SYS_GID_MIN
:系统用户最小 GID,默认为 201。SYS_GID_MAX
:系统用户最大 GID,默认为 999。CREATE_HOME
:是否自动创建用户主目录。UMASK
:主目录的权限,077 表示创建的用户主目录的权限为 700。USERGROUPS_ENAB
:删除用户的同时是否删除其组,默认为 yes。ENCRYPT_METHOD
:密码加密算法,默认为 SHA512。
usermod
使用 usermod
命令修改用户。
常用选项有:
-u UID
:修改 UID,/etc/passwd
中第 3 字段内容-g GID
:修改GID,/etc/passwd
中第 4 字段内容-c comment
:修改备注,/etc/passwd
中第 5 字段内容-d homedir
:修改用户主目录,/etc/passwd
中第 6 字段内容-s loginshell
:修改登录 Shell,/etc/passwd
中第 7 字段内容-G group1,group2
:修改次要组,修改/etc/group
中相关组的第 4 字段-a
:与-G
合用,增加次要组,修改/etc/group
中相关组的第 4 字段-L username
:锁住username
的密码,在/etc/shadow
第 2 字段前增加!
-U username
:解锁username
的密码,去掉/etc/shadow
第 2 字段前的!
为用户增加一个次要组:
[root@stone ~]# id stone
uid=1000(stone) gid=1000(stone) groups=1000(stone)
[root@stone ~]# usermod -G dba stone
[root@stone ~]# id stone
uid=1000(stone) gid=1000(stone) groups=1000(stone),1001(dba)
[root@stone ~]# grep dba /etc/group
dba:x:1001:stone
userdel
使用 userdel
命令删除用户。
常用选项有:
-r
:删除用户的同时删除用户主目录和邮箱目录。
[root@stone ~]# useradd oracle
[root@stone ~]# ll -d /home/oracle/ /var/spool/mail/oracle
drwx------. 2 oracle oracle 62 Jul 16 13:11 /home/oracle/
-rw-rw----. 1 oracle mail 0 Jul 16 13:11 /var/spool/mail/oracle
[root@stone ~]# grep oracle /etc/passwd /etc/shadow /etc/group
/etc/passwd:oracle:x:1001:1002::/home/oracle:/bin/bash
/etc/shadow:oracle:!!:19554:0:99999:7:::
/etc/group:oracle:x:1002:
[root@stone ~]# userdel -r oracle
[root@stone ~]# ll -d /home/oracle/ /var/spool/mail/oracle
ls: cannot access /home/oracle/: No such file or directory
ls: cannot access /var/spool/mail/oracle: No such file or directory
[root@stone ~]# grep oracle /etc/passwd /etc/shadow /etc/group
[root@stone ~]#
passwd
使用 passwd
命令管理用户密码。
常用选项有:
-d
:清空密码,使用户无需密码即可登录-l
:锁住用户的密码,在/etc/shadow
第 2 字段前增加!
-u
:解锁用户的密码,去掉/etc/shadow
第 2 字段前的!
-e
:过期密码-n
:修改密码冻结天数,/etc/shadow
中第 4 字段-x
:修改密码有效天数,/etc/shadow
中第 5 字段-w
:修改密码警告天数,/etc/shadow
中第 6 字段-i
:修改密码宽限天数,/etc/shadow
中第 7 字段,值为宽限日期与 1970-01-01 之间的天数-S
:列出用户密码的相关信息--stdin
:从标准输入读取密码
使用 root
用户可以修改所有用户密码,无需输入原始密码:
[root@stone ~]# passwd stone
Changing password for user stone.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
从标准输入读取密码,为用户设置密码:
[root@stone ~]# echo '123456' | passwd --stdin stone
Changing password for user stone.
passwd: all authentication tokens updated successfully.
查看用户密码信息:
[root@stone ~]# passwd -S stone
stone PS 2023-07-16 0 99999 7 -1 (Password set, SHA512 crypt.)
各字段含义如下:
字段 | 示例 | 含义 |
---|---|---|
1 | stone | 表示用户名 |
2 | PS | 表示用户密码状态,有三种状态: PS = Passworded,表示已设置密码 LK = Locked ,表示已锁住密码 NP = No Password,表示无密码 |
3 | 2023-07-16 | 密码修改日期,/etc/shadow 中第 3 字段 |
4 | 0 | 密码冻结天数,/etc/shadow 中第 4 字段 |
5 | 99999 | 密码有效天数,/etc/shadow 中第 5 字段 |
6 | 7 | 密码警告天数,/etc/shadow 中第 6 字段 |
7 | -1 | 密码宽限天数,/etc/shadow 中第 7 字段,为 -1 表示不会失效 |
修改密码有效天数为 90 天:
[root@stone ~]# passwd -x 90 stone
Adjusting aging data for user stone.
passwd: Success
[root@stone ~]# passwd -S stone
stone PS 2023-07-16 0 90 7 -1 (Password set, SHA512 crypt.)
chage
使用 chage
(change age)命令管理用户密码。
常用选项有:
-l
:列出用户账号密码的详细时间参数-d
:修改密码修改日期,/etc/shadow
中第 3 字段,为0
表示第一次登陆强制修改密码-m
:修改密码冻结天数,/etc/shadow
中第 4 字段-M
:修改密码有效天数,/etc/shadow
中第 5 字段-W
:修改密码警告天数,/etc/shadow
中第 6 字段-I
:修改密码宽限天数,/etc/shadow
中第 7 字段,为-1
表示不会失效-E
:修改账号失效日期,/etc/shadow
中第 8 字段
[root@stone ~]# chage -l stone
Last password change : Jul 16, 2023
Password expires : Oct 14, 2023
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 90
Number of days of warning before password expires : 7
[root@stone ~]# chage -d 2023-06-30 -m 5 -M 180 -W 7 -I 10 -E 2023-12-30 stone
[root@stone ~]# chage -l stone
Last password change : Jun 30, 2023
Password expires : Dec 27, 2023
Password inactive : Jan 06, 2024
Account expires : Dec 30, 2023
Minimum number of days between password change : 5
Maximum number of days between password change : 180
Number of days of warning before password expires : 7
不使用命令选项直接加用户名,可交互修改:
[root@stone ~]# chage stone
Changing the aging information for stone
Enter the new value, or press ENTER for the default
Minimum Password Age [5]: 6
Maximum Password Age [180]: 90
Last Password Change (YYYY-MM-DD) [2023-06-30]: 2023-07-01
Password Expiration Warning [7]: 14
Password Inactive [10]:
Account Expiration Date (YYYY-MM-DD) [2023-12-30]:
[root@stone ~]# chage -l stone
Last password change : Jul 01, 2023
Password expires : Sep 29, 2023
Password inactive : Oct 09, 2023
Account expires : Dec 30, 2023
Minimum number of days between password change : 6
Maximum number of days between password change : 90
Number of days of warning before password expires : 14
su
使用 su
(switch user)命令切换用户。
常用选项有:
-
:切换用户并使用 Login Shell-c
:切换用户并执行命令。
从 root
用户使用 Login Shell 方式切换用户 stone
,无须输入密码:
[root@stone ~]# su - stone
Last login: Sun Jul 16 19:24:00 CST 2023 on pts/0
从 stone
用户使用 Login Shell 方式切换用户 root
,需要输入密码:
[stone@stone ~]$ su - root
Password:
Last login: Mon Jul 17 21:11:22 CST 2023 from 192.168.92.1 on pts/0
在 stone
用户执行命令:
[root@stone ~]# su - stone -c 'pwd'
/home/stone
[root@stone ~]#
sudo
使用 sudo
命令以其他用户的身份执行命令。
常用选项有:
-u
:指定用户,如果不指定,则为root
-l
:列出用户权限-b
:将命令放入后台运行
以 ftp
用户身份创建目录(不能登录到 ftp
用户执行命令,因为 ftp
用户的 Shell 为 /sbin/nologin
):
[root@stone ~]# sudo -u ftp mkdir /tmp/ftp
[root@stone ~]# ll -d /tmp/ftp
drwxr-xr-x 2 ftp ftp 6 Jul 18 10:38 /tmp/ftp
查看 root
用户权限:
[root@stone ~]# sudo -l
Matching Defaults entries for root on stone:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME
HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User root may run the following commands on stone:
(ALL) ALL
查看 stone
用户权限:
[stone@stone ~]$ sudo -l
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for stone:
Sorry, user stone may not run sudo on stone.
可以看到 root
用户可以执行所有命令,而 stone
用户不能运行 sudo
。要使 stone
用户可以运行 sudo
,需要使用 root
用户编辑配置文件 /etc/sudoers
。
[root@stone ~]# cat /etc/sudoers
## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
##
## This file must be edited with the 'visudo' command.
## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
# Host_Alias FILESERVERS = fs1, fs2
# Host_Alias MAILSERVERS = smtp, smtp2
## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
# User_Alias ADMINS = jsmith, mikem
## Command Aliases
## These are groups of related commands...
## Networking
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool
## Installation and management of software
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
## Services
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable
## Updating the locate database
# Cmnd_Alias LOCATE = /usr/bin/updatedb
## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
## Delegating permissions
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp
## Processes
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall
## Drivers
# Cmnd_Alias DRIVERS = /sbin/modprobe
# Defaults specification
#
# Refuse to run if unable to disable echo on the tty.
#
Defaults !visiblepw
#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults always_set_home
Defaults match_group_by_gid
# Prior to version 1.8.15, groups listed in sudoers that were not
# found in the system group database were passed to the group
# plugin, if any. Starting with 1.8.15, only groups of the form
# %:group are resolved via the group plugin by default.
# We enable always_query_group_plugin to restore old behavior.
# Disable this option for new behavior.
Defaults always_query_group_plugin
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults env_keep += "HOME"
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
## user MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL
## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
## Allows members of the users group to mount and unmount the
## cdrom as root
# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom
## Allows members of the users group to shutdown this system
# %users localhost=/sbin/shutdown -h now
## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d
其中:
root ALL=(ALL) ALL
:可以在此行下面增加用户设置root
:第一部分,表示用户为root
ALL=(ALL)
:第二部分,表示来自所有主机ALL
,可以切换为所有用户身份(ALL)
。ALL
:第三部分,表示可以执行所有命令。
%wheel ALL=(ALL) ALL
:可以将用户加入到wheel
组而不需要修改此文件%wheel
:第一部分,表示组为wheel
ALL=(ALL)
:第二部分,表示来自所有主机ALL
,可以切换为所有用户身份(ALL)
。ALL
:第三部分,表示可以执行所有命令。
# %wheel ALL=(ALL) NOPASSWD: ALL
:%wheel
:第一部分,以%
开头,表示组为wheel
ALL=(ALL)
:第二部分,表示来自所有主机ALL
,可以切换为所有用户身份(ALL)
。NOPASSWD: ALL
:第三部分,表示无需输入自身密码。ALL
:第四部分,表示可以执行所有命令。
将 stone
用户加入到 wheel
组,获取 sudo
权限:
[root@stone ~]# usermod -a -G wheel stone
[root@stone ~]# id stone
uid=1000(stone) gid=1000(stone) groups=1000(stone),10(wheel),1001(dba)
[root@stone ~]# su - stone
Last login: Tue Jul 18 10:35:50 CST 2023 on pts/0
[stone@stone ~]$ sudo -l
[sudo] password for stone:
Matching Defaults entries for stone on stone:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME
HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User stone may run the following commands on stone:
(ALL) ALL
或者使用 visudo
命令编辑 /etc/sudoers
文件,为某个用户授予 sudo
权限。
gpasswd
使用 gpasswd
命令管理组。
常用选项有:
-a
:增加用户到组-d
:从组删除用户
从 wheel
组删除 stone
用户:
[root@stone ~]# id stone
uid=1000(stone) gid=1000(stone) groups=1000(stone),10(wheel),1001(dba)
[root@stone ~]# gpasswd -d stone wheel
Removing user stone from group wheel
[root@stone ~]# id stone
uid=1000(stone) gid=1000(stone) groups=1000(stone),1001(dba)
将 stone
用户增加到 wheel
组:
[root@stone ~]# gpasswd -a stone wheel
Adding user stone to group wheel
[root@stone ~]# id stone
uid=1000(stone) gid=1000(stone) groups=1000(stone),10(wheel),1001(dba)
w
使用 w
命令查看当前登录的用户。
[root@stone ~]# w
13:46:36 up 4:51, 2 users, load average: 0.04, 0.05, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.44.1 08:54 3:04m 0.17s 0.17s -bash
root pts/1 192.168.44.1 10:47 4.00s 0.13s 0.00s w
who
使用 who
命令查看当前登录的用户。
[root@stone ~]# who
root pts/0 2023-07-18 08:54 (192.168.44.1)
root pts/1 2023-07-18 10:47 (192.168.44.1)
lastlog
使用 lastlog
命令查看所有用户最近登录时间。
[root@stone ~]# lastlog
Username Port From Latest
root pts/0 192.168.92.1 Tue Jul 18 20:37:45 +0800 2023
bin **Never logged in**
daemon **Never logged in**
adm **Never logged in**
lp **Never logged in**
sync **Never logged in**
shutdown **Never logged in**
halt **Never logged in**
mail **Never logged in**
operator **Never logged in**
games **Never logged in**
ftp **Never logged in**
nobody **Never logged in**
systemd-network **Never logged in**
dbus **Never logged in**
polkitd **Never logged in**
sshd **Never logged in**
postfix **Never logged in**
stone pts/0 Mon Jul 17 21:21:18 +0800 2023
磁盘
本节介绍如何管理磁盘,包括分区,格式化,挂载以及逻辑卷管理。
简介
前面提到,在 Linux 中一切皆文件,磁盘也不例外,磁盘文件位于 /dev
目录下,格式为 /dev/sd[a-z]
,第一个磁盘名称为 /dev/sda
,第一个磁盘的第一个分区为 /dev/sda1
,以此类推。
[root@stone ~]# ll /dev/sd*
brw-rw---- 1 root disk 8, 0 Jul 18 15:20 /dev/sda
brw-rw---- 1 root disk 8, 1 Jul 18 15:20 /dev/sda1
brw-rw---- 1 root disk 8, 2 Jul 18 15:20 /dev/sda2
还可以查看 /proc/partitions
查看系统已识别的磁盘和分区:
[root@stone ~]# cat /proc/partitions
major minor #blocks name
8 0 20971520 sda
8 1 1048576 sda1
8 2 19921920 sda2
11 0 996352 sr0
253 0 17821696 dm-0
253 1 2097152 dm-1
其中 dm-0
,dm-1
为逻辑卷映射:
[root@stone ~]# ll /dev/mapper/centos-*
lrwxrwxrwx. 1 root root 7 Jul 19 21:05 /dev/mapper/centos-root -> ../dm-0
lrwxrwxrwx. 1 root root 7 Jul 19 21:05 /dev/mapper/centos-swap -> ../dm-1
df
使用 df
命令查看磁盘空间使用情况。
常用选项有:
-h
:以易读的单位显示各个分区的大小-i
:显示各个分区的 Inode 使用情况-t
:指定文件系统类型-T
:显示文件系统类型
查看各分区空间使用情况:
[root@stone ~]# df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 898M 0 898M 0% /dev
tmpfs tmpfs 910M 0 910M 0% /dev/shm
tmpfs tmpfs 910M 9.5M 901M 2% /run
tmpfs tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root xfs 17G 1.5G 16G 9% /
/dev/sda1 xfs 1014M 150M 865M 15% /boot
tmpfs tmpfs 182M 0 182M 0% /run/user/0
查看 xfs
文件系统的 Inode 使用情况:
[root@stone ~]# df -i -t xfs
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/centos-root 8910848 31866 8878982 1% /
/dev/sda1 524288 327 523961 1% /boot
du
使用 du
命令查看目录和文件的大小。当某个分区空间使用率很高时,使用 du
命令找到占用空间多的目录和文件。
常用选项有:
-h
:以易读的单位显示各个文件的大小-m
:以 MB 为单位显示各个文件的大小-s
:显示各个目录的总大小
[root@stone ~]# du -sm /var/* | sort -n
0 /var/adm
0 /var/crash
0 /var/empty
0 /var/games
0 /var/gopher
0 /var/kerberos
0 /var/local
0 /var/lock
0 /var/mail
0 /var/nis
0 /var/opt
0 /var/preserve
0 /var/run
0 /var/tmp
0 /var/yp
1 /var/db
1 /var/spool
9 /var/log
58 /var/lib
182 /var/cache
lsblk
使用 lsblk
(list block devices)命令查看所有块设备信息,默认以树形显示。
常用选项有:
-f
:显示文件系统信息
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 973M 0 rom
其中:
NAME
:设备名称MAJ:MIN
:主次设备号RM
:是否为可移动设备SIZE
:容量RO
:是否为只读设备TYPE
:设备类型MOUNTPOINT
:挂载点
查看文件系统类型及 UUID:
[root@stone ~]# lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 xfs 68090631-9520-495e-a71d-b4e712110509 /boot
└─sda2 LVM2_member C8sDj9-yMAj-nMp7-sATx-I1ls-vU3t-woZRfK
├─centos-root xfs 05ef3cb0-4b5d-4480-baa2-2b49e861e6fa /
└─centos-swap swap 6816acb0-bd23-444a-ae69-499f9a3bb3dc [SWAP]
sr0 iso9660 CentOS 7 x86_64 2020-11-03-14-55-29-00
blkid
使用 blkid
命令查看设备的 UUID 及文件系统类型。
[root@stone ~]# blkid
/dev/sda1: UUID="68090631-9520-495e-a71d-b4e712110509" TYPE="xfs"
/dev/sda2: UUID="C8sDj9-yMAj-nMp7-sATx-I1ls-vU3t-woZRfK" TYPE="LVM2_member"
/dev/sr0: UUID="2020-11-03-14-55-29-00" LABEL="CentOS 7 x86_64" TYPE="iso9660" PTTYPE="dos"
/dev/mapper/centos-root: UUID="05ef3cb0-4b5d-4480-baa2-2b49e861e6fa" TYPE="xfs"
/dev/mapper/centos-swap: UUID="6816acb0-bd23-444a-ae69-499f9a3bb3dc" TYPE="swap"
分区
先为虚拟机增加一块磁盘。
在 “虚拟机设置” 页面点击 “添加(A)...”。
选择 “硬盘”,点击 “下一步”。
保持默认的虚拟磁盘类型 “SISI(S)”,点击 “下一步”。
选择 “创建新虚拟磁盘”,点击 “下一步”。
指定最大磁盘大小为 1 GB,选择 “将虚拟磁盘存储为单个文件”,点击 “下一步”。
指定磁盘文件名,点击 “完成”。
可以看到增加了一块容量为 1 GB 的新硬盘,然后启动或重启虚拟机。如果不方便重启,可以执行以下命令让主机识别到新增加的磁盘。
[root@stone ~]# echo "- - -" > $(dirname `grep mpt /sys/class/scsi_host/host?/proc_name | cut -d ':' -f 1`)/scan
处理分区的命令有:
fdisk
:处理 2 TB 以下的分区,针对 MBR 分区格式,在 CentOS 7 版本可用于 GPT(实验阶段)。gdisk
:处理 2 TB 以上的分区,针对 GPT 分区格式。parted
:同时支持 MBR 和 GPT 分区格式。
fdisk
使用 fdisk
命令对 2 TB 以下的磁盘进行分区。
常用选项有:
-l
:列出指定磁盘或者所有磁盘的分区表
列出 /dev/sda
磁盘的分区:
[root@stone ~]# fdisk -l /dev/sda
Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000946ae
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2099199 1048576 83 Linux
/dev/sda2 2099200 41943039 19921920 8e Linux LVM
列出所有磁盘的分区:
[root@stone ~]# fdisk -l
Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000946ae
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2099199 1048576 83 Linux
/dev/sda2 2099200 41943039 19921920 8e Linux LVM
Disk /dev/sdb: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/centos-root: 18.2 GB, 18249416704 bytes, 35643392 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/centos-swap: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
可以看到磁盘 /dev/sdb
没有分区,下面对其进行分区。
[root@stone ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x6b830a5a.
Command (m for help):
进入交互界面后,输入 m
获取帮助:
Command (m for help): m
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
g create a new empty GPT partition table
G create an IRIX (SGI) partition table
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)
其中:
p
:输出分区表n
:新建分区l
:列出分区类型d
:删除分区q
:不保存退出w
:保存退出
先查看当前分区:
Command (m for help): p
Disk /dev/sdb: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x6b830a5a
Device Boot Start End Blocks Id System
可以看到还没有分区,新建分区:
Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p):
此处需要选择分区类型:
primary
:主分区,最多 4 个extended
:扩展分区,最多 1 个logic
:逻辑分区,在扩展分区中,可以多个。
此处创建主分区,默认也是主分区,直接回车即可:
Using default response p
Partition number (1-4, default 1):
此处需要指定分区号,默认为 1,即 sdb1,回车即可:
Partition number (1-4, default 1):
First sector (2048-2097151, default 2048):
此处需要指定开始扇区号,保持默认,回车:
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-2097151, default 2097151):
此处需要指定结束扇区号,默认到磁盘最后,可以指定大小,如果要将整个磁盘作为 1 个分区,回车即可:
Using default value 2097151
Partition 1 of type Linux and of size 1023 MiB is set
再次查看分区:
Command (m for help): p
Disk /dev/sdb: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x6b830a5a
Device Boot Start End Blocks Id System
/dev/sdb1 2048 2097151 1047552 83 Linux
可以看到增加了一个分区了,保存退出:
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
查看分区信息:
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 1G 0 disk
└─sdb1 8:17 0 1023M 0 part
sr0 11:0 1 973M 0 rom
gdisk
使用 gdisk
命令对磁盘进行分区。
常用选项有:
-l
:列出指定磁盘的分区表
参考上面的步骤,为虚拟机再增加一块磁盘,然后使用 gdisk
命令对磁盘进行分区。
先查看 /dev/sdc
的分区:
[root@stone ~]# gdisk -l /dev/sdc
GPT fdisk (gdisk) version 0.8.10
Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: not present
Creating new GPT entries.
Disk /dev/sdc: 2097152 sectors, 1024.0 MiB
Logical sector size: 512 bytes
Disk identifier (GUID): CD5C1EFB-5F02-4DB5-A2EF-D7B0485B65BB
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 2097118
Partitions will be aligned on 2048-sector boundaries
Total free space is 2097085 sectors (1024.0 MiB)
Number Start (sector) End (sector) Size Code Name
可以看到还没有分区,下面对 /dev/sdc
进行分区:
[root@stone ~]# gdisk /dev/sdc
GPT fdisk (gdisk) version 0.8.10
Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: not present
Creating new GPT entries.
Command (? for help):
进入交互界面后,输入 ?
获取帮助:
Command (? for help): ?
b back up GPT data to a file
c change a partition's name
d delete a partition
i show detailed information on a partition
l list known partition types
n add a new partition
o create a new empty GUID partition table (GPT)
p print the partition table
q quit without saving changes
r recovery and transformation options (experts only)
s sort partitions
t change a partition's type code
v verify disk
w write table to disk and exit
x extra functionality (experts only)
? print this menu
其中:
p
:输出分区表n
:新建分区l
:列出分区类型d
:删除分区q
:不保存退出w
:保存退出
先查看当前分区:
Command (? for help): p
Disk /dev/sdc: 2097152 sectors, 1024.0 MiB
Logical sector size: 512 bytes
Disk identifier (GUID): 8323B871-94ED-491D-B238-69151D276EC5
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 2097118
Partitions will be aligned on 2048-sector boundaries
Total free space is 2097085 sectors (1024.0 MiB)
Number Start (sector) End (sector) Size Code Name
可以看到还没有分区,新建分区:
Command (? for help): n
Partition number (1-128, default 1):
此处需要指定分区号,默认从 1 开始,直接回车即可:
First sector (34-2097118, default = 2048) or {+-}size{KMGTP}:
此处需要指定开始扇区号,保持默认,回车:
Last sector (2048-2097118, default = 2097118) or {+-}size{KMGTP}:
此处需要指定结束扇区号,默认到磁盘最后,可以指定大小,如果要将整个磁盘作为 1 个分区,回车即可:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
此处指定分区的文件系统,默认为 Linux filesystem,代码为 8300,保持默认,回车即可:
Changed type of partition to 'Linux filesystem'
Command (? for help):
再次查看分区:
Command (? for help): p
Disk /dev/sdc: 2097152 sectors, 1024.0 MiB
Logical sector size: 512 bytes
Disk identifier (GUID): 8323B871-94ED-491D-B238-69151D276EC5
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 2097118
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 2097118 1023.0 MiB 8300 Linux filesystem
可以看到增加了一个分区了,保存退出:
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdc.
The operation has completed successfully.
查看分区信息:
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 1G 0 disk
└─sdb1 8:17 0 1023M 0 part
sdc 8:32 0 1G 0 disk
└─sdc1 8:33 0 1023M 0 part
sr0 11:0 1 973M 0 rom
parted
使用 parted
命令对磁盘进行分区。
常用选项有:
-l
:列出所有磁盘的分区表-s
:脚本模式
参考上面的步骤,为虚拟机再增加一块磁盘,然后使用 parted
命令对磁盘进行分区。
先查看当前磁盘分区:
[root@stone ~]# parted -l
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sda: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 1075MB 1074MB primary xfs boot
2 1075MB 21.5GB 20.4GB primary lvm
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 1074MB 1073MB primary
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdc: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 1074MB 1073MB Linux filesystem
Error: /dev/sdd: unrecognised disk label
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdd: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: unknown
Disk Flags:
Model: Linux device-mapper (linear) (dm)
Disk /dev/mapper/centos-swap: 2147MB
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:
Number Start End Size File system Flags
1 0.00B 2147MB 2147MB linux-swap(v1)
Model: Linux device-mapper (linear) (dm)
Disk /dev/mapper/centos-root: 18.2GB
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:
Number Start End Size File system Flags
1 0.00B 18.2GB 18.2GB xfs
Warning: Unable to open /dev/sr0 read-write (Read-only file system). /dev/sr0
has been opened read-only.
Model: NECVMWar VMware IDE CDR10 (scsi)
Disk /dev/sr0: 1020MB
Sector size (logical/physical): 2048B/2048B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
2 909kB 37.0MB 36.0MB primary
可以看到磁盘 /dev/sdd
没有分区,下面对其进行分区。
[root@stone ~]# parted /dev/sdd
GNU Parted 3.1
Using /dev/sdd
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted)
进入交互界面后,输入 help
获取帮助:
(parted) help
align-check TYPE N check partition N for TYPE(min|opt) alignment
help [COMMAND] print general help, or help on COMMAND
mklabel,mktable LABEL-TYPE create a new disklabel (partition table)
mkpart PART-TYPE [FS-TYPE] START END make a partition
name NUMBER NAME name partition NUMBER as NAME
print [devices|free|list,all|NUMBER] display the partition table, available devices, free space,
all found partitions, or a particular partition
quit exit program
rescue START END rescue a lost partition near START and END
resizepart NUMBER END resize partition NUMBER
rm NUMBER delete partition NUMBER
select DEVICE choose the device to edit
disk_set FLAG STATE change the FLAG on selected device
disk_toggle [FLAG] toggle the state of FLAG on selected device
set NUMBER FLAG STATE change the FLAG on partition NUMBER
toggle [NUMBER [FLAG]] toggle the state of FLAG on partition NUMBER
unit UNIT set the default unit to UNIT
version display the version number and copyright information of GNU
Parted
(parted)
其中:
mklabel
:设置分区类型mkpart
:创建分区print
:显示分区信息quit
:退出rm
:删除分区
先查看当前分区:
(parted) print
Error: /dev/sdd: unrecognised disk label
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdd: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: unknown
Disk Flags:
可以看到还没有分区,先设置分区类型:
(parted) mklabel gpt
(parted) print
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdd: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
再创建分区:
(parted) help mkpart
mkpart PART-TYPE [FS-TYPE] START END make a partition
PART-TYPE is one of: primary, logical, extended
FS-TYPE is one of: btrfs, nilfs2, ext4, ext3, ext2, fat32, fat16, hfsx, hfs+, hfs, jfs, swsusp,
linux-swap(v1), linux-swap(v0), ntfs, reiserfs, hp-ufs, sun-ufs, xfs, apfs2, apfs1, asfs,
amufs5, amufs4, amufs3, amufs2, amufs1, amufs0, amufs, affs7, affs6, affs5, affs4, affs3, affs2,
affs1, affs0, linux-swap, linux-swap(new), linux-swap(old)
START and END are disk locations, such as 4GB or 10%. Negative values count from the end of the
disk. For example, -1s specifies exactly the last sector.
'mkpart' makes a partition without creating a new file system on the partition. FS-TYPE may be
specified to set an appropriate partition ID.
(parted) mkpart primary 2048s -1s
Warning: You requested a partition from 1049kB to 1074MB (sectors 2048..2097151).
The closest location we can manage is 1049kB to 1074MB (sectors 2048..2097118).
Is this still acceptable to you?
Yes/No? Yes
再次查看分区:
(parted) print
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdd: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 1074MB 1073MB primary
可以看到增加了一个分区了,直接退出:
(parted) quit
Information: You may need to update /etc/fstab.
查看分区信息:
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 1G 0 disk
└─sdb1 8:17 0 1023M 0 part
sdc 8:32 0 1G 0 disk
└─sdc1 8:33 0 1023M 0 part
sdd 8:48 0 1G 0 disk
└─sdd1 8:49 0 1023M 0 part
sr0 11:0 1 973M 0 rom
还可以直接在命令行使用 parted
命令执行分区操作,比如上面的分区操作可以使用以下命令完成:
[root@stone ~]# parted -s /dev/sdd mklabel gpt
[root@stone ~]# parted -s /dev/sdd mkpart primary 2048s -1s
[root@stone ~]# parted -s /dev/sdd print
格式化
对磁盘进行分区后,需要指定文件类型对其进行格式化,创建文件系统。
常用的文件类型如下:
Type | File system | Attributes and use cases |
---|---|---|
Disk or local FS | XFS | XFS is the default file system in RHEL. Because it lays out files as extents, it is less vulnerable to fragmentation than ext4. Red Hat recommends deploying XFS as your local file system unless there are specific reasons to do otherwise: for example, compatibility or corner cases around performance. |
Disk or local FS | ext4 | ext4 has the benefit of longevity in Linux. Therefore, it is supported by almost all Linux applications. In most cases, it rivals XFS on performance. ext4 is commonly used for home directories. |
Network or client-and-server FS | NFS | Use NFS to share files between multiple systems on the same network. |
Network or client-and-server FS | SMB | Use SMB for file sharing with Microsoft Windows systems. |
Shared storage or shared disk FS | GFS2 | GFS2 provides shared write access to members of a compute cluster. The emphasis is on stability and reliability, with the functional experience of a local file system as possible. SAS Grid, Tibco MQ, IBM Websphere MQ, and Red Hat Active MQ have been deployed successfully on GFS2. |
Volume-managing FS | Stratis (Technology Preview) | Stratis is a volume manager built on a combination of XFS and LVM. The purpose of Stratis is to emulate capabilities offered by volume-managing file systems like Btrfs and ZFS. It is possible to build this stack manually, but Stratis reduces configuration complexity, implements best practices, and consolidates error information. |
对于本地文件系统,建议:
- XFS:CentOS 7 默认文件系统类型。
- ext4:CentOS 6 默认文件系统类型。
mkfs.xfs
使用 mkfs.xfs
命令将分区格式化为 XFS 文件系统类型。
常用选项有:
-L
:为文件系统指定一个 Label,不超过 12 个字符。
格式化前查看分区信息:
[root@stone ~]# lsblk -f /dev/sdb
NAME FSTYPE LABEL UUID MOUNTPOINT
sdb
└─sdb1
格式化:
[root@stone ~]# mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1 isize=512 agcount=4, agsize=65472 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=261888, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=855, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
格式化后查看分区信息:
[root@stone ~]# lsblk -f /dev/sdb
NAME FSTYPE LABEL UUID MOUNTPOINT
sdb
└─sdb1 xfs daf8b47d-842a-476d-8e18-5da4a4a15d6d
挂载
将分区格式化为 XFS 文件系统后,需要挂载到空目录才能使用。
mount
使用 mount
命令挂载文件系统到指定目录。
常用选项有:
-a
:挂载文件/etc/fstab
中的所有文件系统。-t
:指定挂载的文件系统类型,在 CentOS 7 可以不指定,系统自动识别。-n
:不会将挂载信息写入到/etc/mtab
,当/etc
目录只读时需使用此选项。-o
:指定挂载参数,常用参数有:atime
,noatime
:读取文件时是否更新其 atimero
,rw
:挂载文件系统为只读或可读写remount
:重新挂载
挂载前查看当前的挂载情况:
[root@stone ~]# mount | grep /dev/sd
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
创建目录并挂载:
[root@stone ~]# mkdir -p /data/sdb1
[root@stone ~]# mount /dev/sdb1 /data/sdb1/
再次查看挂载情况:
[root@stone ~]# mount | grep /dev/sd
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
/dev/sdb1 on /data/sdb1 type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
[root@stone ~]# lsblk -f /dev/sdb
NAME FSTYPE LABEL UUID MOUNTPOINT
sdb
└─sdb1 xfs daf8b47d-842a-476d-8e18-5da4a4a15d6d /data/sdb1
[root@stone ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 898M 0 898M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.6M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.5G 16G 9% /
/dev/sda1 1014M 150M 865M 15% /boot
tmpfs 182M 0 182M 0% /run/user/0
/dev/sdb1 1020M 33M 988M 4% /data/sdb1
还可以将光盘挂载到指定目录:
[root@stone ~]# mount /dev/sr0 /media/
mount: /dev/sr0 is write-protected, mounting read-only
[root@stone ~]# ls /media/
CentOS_BuildTag EULA images LiveOS repodata RPM-GPG-KEY-CentOS-Testing-7
EFI GPL isolinux Packages RPM-GPG-KEY-CentOS-7 TRANS.TBL
挂载文件系统到指定目录后,就可以对其进行写入和读取了,但是如果重启了主机,就会发现之前挂载的文件系统不见了,如果要使用,就得再挂载一下。此时就需要使用 /etc/fstab
文件了,将挂载信息写入到此文件中,主机在启动的时候就会读取该文件,并进行挂载。
[root@stone ~]# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Thu Jun 22 20:37:31 2023
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=68090631-9520-495e-a71d-b4e712110509 /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
其中:
/dev/mapper/centos-root
:第 1 项,指定需要挂载的对象,可以是分区名称,UUID 或者 LABEL。/
:第 2 项,指定挂载目录。xfs
:第 3 项,指定文件系统类型。defaults
:第 4 项,指定挂载参数,一般为defaults
,表示:rw,suid,dev,exec,auto,nouser 和 async。0
:第 5 项,指定是否支持dump
备份,一般无需支持,保持为0
。0
:第 6 项,指定是否需要在开机时使用fsck
检查文件系统,不适用于 XFS 文件系统,保持为0
。
将新创建的文件系统加入到 /etc/fstab
文件中,在最后面添加一行:
[root@stone ~]# vi /etc/fstab
#
# /etc/fstab
# Created by anaconda on Thu Jun 22 20:37:31 2023
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=68090631-9520-495e-a71d-b4e712110509 /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/dev/sdb1 /data/sdb1/ xfs defaults 0 0
然后挂载该文件中的所有文件系统:
[root@stone ~]# mount -a
查看挂载情况:
[root@stone ~]# mount | grep /dev/sdb
/dev/sdb1 on /data/sdb1 type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
[root@stone ~]# df -h | grep /dev/sdb
/dev/sdb1 1020M 33M 988M 4% /data/sdb1
umount
使用 umount
卸载文件系统。
常用选项有:
-f
:强制卸载,经常用于无法访问的 NFS 文件系统。-l
:当使用-f
失败时,可以使用此选项。
卸载前面挂载的文件系统:
[root@stone ~]# umount /data/sdb1
卸载的时候,不能有进程使用该文件系统,否则需要终止相关进程或者使用 -l
选项才能卸载。
[root@stone ~]# cd /data/sdb1/
[root@stone sdb1]# umount /data/sdb1
umount: /data/sdb1: target is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
[root@stone sdb1]# umount -l /data/sdb1
使用 umount
命令卸载只是临时卸载,要永久生效,需要删除或者注释 /etc/fstab
中对应条目。
逻辑卷管理
考虑如下情况,将一个 100 GB 的分区格式化并挂载到某个目录后,随着数据量的增加,会将该分区写满,那么该如何应对这种数据不断增长的情况呢。是重新挂载一个 200 GB 的分区,然后将原分区的数据拷贝到新分区吗,当然不需要这么麻烦。在实际工作中,都会使用逻辑卷管理(Logical Volume Manager LVM)来处理这种需求,弹性调整文件系统的大小。
LVM 包括:
- PV(Physical Volume):物理卷,由分区创建。
- VG(Volume Group):卷组,由多个 PV 组成,并划分成多个 PE(Physical Extent),作为逻辑卷的最小存储单元。
- LV(Logical Volume):逻辑卷,由多个 PE 组成。
创建逻辑卷的步骤:
- 创建分区,使用
gdisk
命令 - 创建 PV,使用
pvcreate
命令 - 创建 VG,使用
vgcreate
命令 - 创建 LV,使用
lvcreate
命令 - 格式化和挂载,使用
mkfs.xfs
和mount
命令
创建分区
为虚拟机增加 2 块 1 GB 磁盘,使用 gdisk
命令创建分区。
创建分区前:
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 1G 0 disk
└─sdb1 8:17 0 1023M 0 part /data/sdb1
sdc 8:32 0 1G 0 disk
└─sdc1 8:33 0 1023M 0 part
sdd 8:48 0 1G 0 disk
└─sdd1 8:49 0 1023M 0 part
sde 8:64 0 1G 0 disk
sdf 8:80 0 1G 0 disk
sr0 11:0 1 973M 0 rom
使用 gdisk
命令创建分区,与之前不同的是,需要指定分区编码为 8e00
:
Hex code or GUID (L to show codes, Enter = 8300): 8e00
Changed type of partition to 'Linux LVM'
创建分区后:
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 1G 0 disk
└─sdb1 8:17 0 1023M 0 part /data/sdb1
sdc 8:32 0 1G 0 disk
└─sdc1 8:33 0 1023M 0 part
sdd 8:48 0 1G 0 disk
└─sdd1 8:49 0 1023M 0 part
sde 8:64 0 1G 0 disk
└─sde1 8:65 0 1023M 0 part
sdf 8:80 0 1G 0 disk
└─sdf1 8:81 0 1023M 0 part
sr0 11:0 1 973M 0 rom
创建 PV
相关命令有:
pvcreate
:创建 PVpvscan
:列出 PVpvdisplay
:列出 PV 详细信息pvremove
:删除 PV
[root@stone ~]# pvscan
PV /dev/sda2 VG centos lvm2 [<19.00 GiB / 0 free]
Total: 1 [<19.00 GiB] / in use: 1 [<19.00 GiB] / in no VG: 0 [0 ]
[root@stone ~]# pvcreate /dev/sde1 /dev/sdf1
Physical volume "/dev/sde1" successfully created.
Physical volume "/dev/sdf1" successfully created.
[root@stone ~]# pvscan
PV /dev/sda2 VG centos lvm2 [<19.00 GiB / 0 free]
PV /dev/sde1 lvm2 [1022.98 MiB]
PV /dev/sdf1 lvm2 [1022.98 MiB]
Total: 3 [20.99 GiB] / in use: 1 [<19.00 GiB] / in no VG: 2 [<2.00 GiB]
[root@stone ~]# pvdisplay /dev/sde1
"/dev/sde1" is a new physical volume of "1022.98 MiB"
--- NEW Physical volume ---
PV Name /dev/sde1
VG Name
PV Size 1022.98 MiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID v7Fnm3-gt9R-lX5v-9pVz-26A2-oed7-YjoBL1
[root@stone ~]# pvdisplay /dev/sdf1
"/dev/sdf1" is a new physical volume of "1022.98 MiB"
--- NEW Physical volume ---
PV Name /dev/sdf1
VG Name
PV Size 1022.98 MiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID xP932c-wx0f-yQOp-Gg9p-qTry-k7zv-SsC38c
由于 PE 是在创建 VG 时指定,故此时看到的 PV 里面的 PE 都是 0
。
创建 VG
基于 PV 创建 VG ,相关命令有:
vgcreate
:创建 VG,常用选项有:-s
:指定 PE 大小,默认为 4 MB。
vgscan
:列出 VGvgdisplay
:列出 VG 详细信息vgextend
:增加 PV 到 VGvgreduce
:从 VG 中移除 PVvgchange
:修改 VG 属性,常用选项有:-a
:指定 VG 是否激活,如果要删除该 VG,则需指定为n
。
vgremove
:删除 VG
[root@stone ~]# vgscan
Reading volume groups from cache.
Found volume group "centos" using metadata type lvm2
[root@stone ~]# vgcreate stonevg /dev/sde1 /dev/sdf1
Volume group "stonevg" successfully created
[root@stone ~]# vgscan
Reading volume groups from cache.
Found volume group "stonevg" using metadata type lvm2
Found volume group "centos" using metadata type lvm2
[root@stone ~]# vgdisplay stonevg
--- Volume group ---
VG Name stonevg
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 1.99 GiB
PE Size 4.00 MiB
Total PE 510
Alloc PE / Size 0 / 0
Free PE / Size 510 / 1.99 GiB
VG UUID vYEARm-IZij-B6N1-yWeS-oGF1-z2qM-BuBzzg
可以看到 stonevg
的大小约为 2 GB,PE 大小为 4 MB,共有 510 个 PE,目前还没有分配给 LV。
此时使用 pvdisplay
查看之前创建的 PV:、
[root@stone ~]# pvdisplay /dev/sde1
--- Physical volume ---
PV Name /dev/sde1
VG Name stonevg
PV Size 1022.98 MiB / not usable 2.98 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 255
Free PE 255
Allocated PE 0
PV UUID v7Fnm3-gt9R-lX5v-9pVz-26A2-oed7-YjoBL1
[root@stone ~]# pvdisplay /dev/sdf1
--- Physical volume ---
PV Name /dev/sdf1
VG Name stonevg
PV Size 1022.98 MiB / not usable 2.98 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 255
Free PE 255
Allocated PE 0
PV UUID xP932c-wx0f-yQOp-Gg9p-qTry-k7zv-SsC38c
可以看到这两个 PV 的 VG Name 为 stonevg
,PE Size 为 4 MB,Total PE 为 255。
创建 LV
基于 VG 创建 LV,相关命令有:
lvcreate
:创建 LV,常用选项有:-L
:指定 LV 大小,单位可以是 M,G,T 等-l
:指定 LV 大小,后面是 PE 个数-n
:指定 LV 名称
lvscan
:列出 LVlvdisplay
:列出 LV 详细信息lvextend
:扩展 LVlvreduce
:缩小 LVlvresize
:调整 LV 容量lvremove
:删除 LV
[root@stone ~]# lvscan
ACTIVE '/dev/centos/swap' [2.00 GiB] inherit
ACTIVE '/dev/centos/root' [<17.00 GiB] inherit
[root@stone ~]# lvcreate -L 1G -n stonelv1 stonevg
Logical volume "stonelv1" created.
[root@stone ~]# lvcreate -L 1G -n stonelv2 stonevg
Volume group "stonevg" has insufficient free space (254 extents): 256 required.
[root@stone ~]# lvcreate -l 254 -n stonelv2 stonevg
Logical volume "stonelv2" created.
[root@stone ~]# lvscan
ACTIVE '/dev/stonevg/stonelv1' [1.00 GiB] inherit
ACTIVE '/dev/stonevg/stonelv2' [1016.00 MiB] inherit
ACTIVE '/dev/centos/swap' [2.00 GiB] inherit
ACTIVE '/dev/centos/root' [<17.00 GiB] inherit
[root@stone ~]# lvdisplay /dev/stonevg/stonelv1
--- Logical volume ---
LV Path /dev/stonevg/stonelv1
LV Name stonelv1
VG Name stonevg
LV UUID Oo3125-3ryt-TXXn-CjlR-6x98-x3XZ-3kheYf
LV Write Access read/write
LV Creation host, time stone, 2023-07-23 13:01:52 +0800
LV Status available
# open 0
LV Size 1.00 GiB
Current LE 256
Segments 2
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:2
[root@stone ~]# lvdisplay /dev/stonevg/stonelv2
--- Logical volume ---
LV Path /dev/stonevg/stonelv2
LV Name stonelv2
VG Name stonevg
LV UUID MmptiA-YNx5-W0n3-l011-qbge-Rg00-ZSKIzY
LV Write Access read/write
LV Creation host, time stone, 2023-07-23 13:04:34 +0800
LV Status available
# open 0
LV Size 1016.00 MiB
Current LE 254
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:3
此时查看 VG 可以看到已经将所有 PE 分配给了 LV:
[root@stone ~]# vgdisplay stonevg
--- Volume group ---
VG Name stonevg
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 3
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 2
Act PV 2
VG Size 1.99 GiB
PE Size 4.00 MiB
Total PE 510
Alloc PE / Size 510 / 1.99 GiB
Free PE / Size 0 / 0
VG UUID vYEARm-IZij-B6N1-yWeS-oGF1-z2qM-BuBzzg
格式化和挂载
使用 mkfs.xfs
和 mount
命令进行格式化和挂载。
[root@stone ~]# mkfs.xfs /dev/stonevg/stonelv1
meta-data=/dev/stonevg/stonelv1 isize=512 agcount=4, agsize=65536 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=262144, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@stone ~]# mkfs.xfs /dev/stonevg/stonelv2
meta-data=/dev/stonevg/stonelv2 isize=512 agcount=4, agsize=65024 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=260096, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=855, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@stone ~]# mkdir /data/stonelv1 /data/stonelv2
[root@stone ~]# mount /dev/stonevg/stonelv1 /data/stonelv1
[root@stone ~]# mount /dev/stonevg/stonelv2 /data/stonelv2
[root@stone ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 898M 0 898M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.6M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.5G 16G 9% /
/dev/sdb1 1020M 33M 988M 4% /data/sdb1
/dev/sda1 1014M 150M 865M 15% /boot
tmpfs 182M 0 182M 0% /run/user/0
/dev/mapper/stonevg-stonelv1 1014M 33M 982M 4% /data/stonelv1
/dev/mapper/stonevg-stonelv2 1013M 33M 981M 4% /data/stonelv2
扩展 LV
创建逻辑卷的步骤:
- 创建分区,使用
gdisk
命令 - 创建 PV,使用
pvcreate
命令 - 扩展 VG,使用
vgextend
命令 - 扩展 LV,使用
lvextend
命令 - 扩展文件系统,使用
xfs_growfs
命令
假设扩展逻辑卷 stonelv2
,由于此时卷组 stonevg
没有剩余空间了,故需要先增加磁盘,再分区,创建物理卷,然后扩展卷组,才能扩展逻辑卷,最后再扩展文件系统。
为虚拟机增加 1 块 1 GB 磁盘,使用 gdisk
命令创建分区,结果如下:
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─centos-root 253:0 0 17G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 1G 0 disk
└─sdb1 8:17 0 1023M 0 part /data/sdb1
sdc 8:32 0 1G 0 disk
└─sdc1 8:33 0 1023M 0 part
sdd 8:48 0 1G 0 disk
└─sdd1 8:49 0 1023M 0 part
sde 8:64 0 1G 0 disk
└─sde1 8:65 0 1023M 0 part
└─stonevg-stonelv1 253:2 0 1G 0 lvm /data/stonelv1
sdf 8:80 0 1G 0 disk
└─sdf1 8:81 0 1023M 0 part
├─stonevg-stonelv1 253:2 0 1G 0 lvm /data/stonelv1
└─stonevg-stonelv2 253:3 0 1016M 0 lvm /data/stonelv2
sdg 8:96 0 1G 0 disk
└─sdg1 8:97 0 1023M 0 part
sr0 11:0 1 973M 0 rom
使用 pvcreate
命令创建 PV:
[root@stone ~]# pvcreate /dev/sdg1
Physical volume "/dev/sdg1" successfully created.
[root@stone ~]# pvdisplay /dev/sdg1
"/dev/sdg1" is a new physical volume of "1022.98 MiB"
--- NEW Physical volume ---
PV Name /dev/sdg1
VG Name
PV Size 1022.98 MiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID ZYy1WB-DBA3-mdvp-rQ2d-NJVs-BUrg-Vax5pH
使用 vgextend
命令扩展 VG:
[root@stone ~]# vgextend stonevg /dev/sdg1
Volume group "stonevg" successfully extended
[root@stone ~]# vgdisplay stonevg
--- Volume group ---
VG Name stonevg
System ID
Format lvm2
Metadata Areas 3
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 3
Act PV 3
VG Size <2.99 GiB
PE Size 4.00 MiB
Total PE 765
Alloc PE / Size 510 / 1.99 GiB
Free PE / Size 255 / 1020.00 MiB
VG UUID vYEARm-IZij-B6N1-yWeS-oGF1-z2qM-BuBzzg
可以看到增加了 255 个 PE。
使用 lvextend
命令扩展 LV,常用选项有:
-L
:指定 LV 大小,单位可以是 M,G,T 等,使用+
表示增加多少空间,不使用则表示扩展到多少空间-l
:指定 LV 大小,后面是 PE 个数,使用+
表示增加多少 PE,不使用则表示扩展到多少 PE
[root@stone ~]# lvextend -l +255 /dev/stonevg/stonelv2
Size of logical volume stonevg/stonelv2 changed from 1016.00 MiB (254 extents) to <1.99 GiB (509 extents).
Logical volume stonevg/stonelv2 successfully resized.
[root@stone ~]# lvdisplay /dev/stonevg/stonelv2
--- Logical volume ---
LV Path /dev/stonevg/stonelv2
LV Name stonelv2
VG Name stonevg
LV UUID MmptiA-YNx5-W0n3-l011-qbge-Rg00-ZSKIzY
LV Write Access read/write
LV Creation host, time stone, 2023-07-23 13:04:34 +0800
LV Status available
# open 1
LV Size <1.99 GiB
Current LE 509
Segments 2
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:3
使用 xfs_growfs
命令扩展文件系统:
[root@stone ~]# df -h /data/stonelv2
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/stonevg-stonelv2 1013M 33M 981M 4% /data/stonelv2
[root@stone ~]# xfs_growfs /data/stonelv2
meta-data=/dev/mapper/stonevg-stonelv2 isize=512 agcount=4, agsize=65024 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0 spinodes=0
data = bsize=4096 blocks=260096, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=855, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 260096 to 521216
[root@stone ~]# df -h /data/stonelv2
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/stonevg-stonelv2 2.0G 33M 2.0G 2% /data/stonelv2
可以看到 /data/stonelv2
从 1 GB 扩展到 2 GB。
总结
对于逻辑卷管理涉及到的阶段和命令如下表:
PV | VG | LV | XFS | ext4 | |
---|---|---|---|---|---|
scan | pvscan | vgscan | lvscan | lsblk, blkid | lsblk, blkid |
create | pvcreate | vgcreate | lvcreate | mkfs.xfs | mkfs.ext4 |
display | pvdisplay | vgdisplay | lvdisplay | df, mount | df, mount |
extend | vgextend | lvextend (lvresize) | xfs_growfs | resize2fs | |
reduce | vgreduce | lvreduce (lvresize) | resize2fs | ||
remove | pvremove | vgremove | lvremove | umount | umount |
resize | lvresize | xfs_growfs | resize2fs | ||
change | pvchange | vgchange | lvchange | /etc/fstab, remount | /etc/fstab, remount |
内存
Linux 的内存管理非常复杂,本文不涉及内存管理的原理及体系,只说明在实际工作中如何查看内存以及调整内存。
内存信息
这里只介绍查看系统整体内存使用情况的命令,对于各个进程使用内存的情况,将在进程章节详细介绍。
free
使用 free
命令查看系统内存使用情况。
-h
:以易读方式显示内存大小-k
:以 KB 为单位-m
:以 MB 为单位-g
:以 GB 为单位-w
:buffers
和cache
分开显示-s
:指定刷新间隔秒数,连续显示-c
:与-s
配合,指定刷新次数
[root@stone ~]# free -m -w
total used free shared buffers cache available
Mem: 3931 1863 1496 14 2 569 1835
Swap: 2047 0 2047
其中:
- 第 2 行显示物理内存使用情况,为
/proc/meminfo
的相关内容项,包括:total
:总内存,为/proc/meminfo
中的MemTotal
used
:已用内存,为total - free - buffers - cache
free
:未使用内存,为/proc/meminfo
中的MemFree
shared
:被 tmpfs 使用的内存,为/proc/meminfo
中的Shmem
buff
:内核缓冲(kernel buffers),为/proc/meminfo
中的Buffers
cache
:是页面缓存(page cache)和 slabs,为/proc/meminfo
中的Cached
和SReclaimable
available
:可用物理内存,为/proc/meminfo
中的MemAvailable
- 第 3 行显示 SWAP 使用情况,包括:
total
:总 SWAP,为/proc/meminfo
中的SwapTotal
used
:已用 SWAP,为total - free
free
:未使用 SWAP,为/proc/meminfo
中的SwapFree
直接查看文件 /proc/meminfo
获取内存详细信息:
[root@stone ~]# cat /proc/meminfo
MemTotal: 4026164 kB
MemFree: 1528584 kB
MemAvailable: 1876072 kB
Buffers: 2112 kB
Cached: 546068 kB
SwapCached: 0 kB
Active: 838756 kB
Inactive: 387320 kB
Active(anon): 678660 kB
Inactive(anon): 13592 kB
Active(file): 160096 kB
Inactive(file): 373728 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 677896 kB
Mapped: 93216 kB
Shmem: 14356 kB
Slab: 106496 kB
SReclaimable: 37520 kB
SUnreclaim: 68976 kB
KernelStack: 7808 kB
PageTables: 23768 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3585940 kB
Committed_AS: 2018728 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 188972 kB
VmallocChunk: 34359310332 kB
Percpu: 25600 kB
HardwareCorrupted: 0 kB
AnonHugePages: 532480 kB
CmaTotal: 0 kB
CmaFree: 0 kB
HugePages_Total: 512
HugePages_Free: 482
HugePages_Rsvd: 432
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 98112 kB
DirectMap2M: 4096000 kB
DirectMap1G: 2097152 kB
SWAP
使用 lsblk
命令查看所有块设备信息:
[root@stone ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
fd0 2:0 1 4K 0 disk
sda 8:0 0 40G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 39G 0 part
├─centos-root 253:0 0 37G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 1G 0 rom
可以看到有一个 SWAP 分区,这个分区是在安装系统时创建的。在物理内存不足时,可以使用 SWAP 分区来临时存放内存中暂不使用的数据,相当于临时扩展了物理内存。由于 SWAP 分区是位于磁盘上面的,其速度远低于内存,基于性能考虑,应尽量避免系统使用到 SWAP。但在某些时候,由于物理内存不足,比如云主机,为了避免出现 OOM 的情况,可以考虑添加 SWAP 分区。
添加 SWAP 分区可以使用分区来添加,也可以直接使用文件。在实际工作中,往往没有多余的分区,更多是通过使用文件来添加。步骤如下:
- 使用
dd
命令创建一个 1 GB 的文件
[root@stone ~]# dd if=/dev/zero of=/root/swap bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 2.90622 s, 369 MB/s
[root@stone ~]# ll -h /root/swap
-rw-r--r--. 1 root root 1.0G Jul 25 20:27 /root/swap
其中:
if
:指定输入文件(Input File),/dev/zero
提供无限连续不断的空的数据流of
:指定输出文件(Output File)bs
:指定输入和输出的块大小(Block Size)count
:指定块数量
- 使用
mkswap
命令将/root/swap
文件格式化为 SWAP 格式
[root@stone ~]# mkswap /root/swap
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=46a4a37a-b4f0-413e-b0ac-d7260219ba0d
- 使用
swapon
命令启用/root/swap
,然后使用swapon -s
命令查看
[root@stone ~]# swapon /root/swap
swapon: /root/swap: insecure permissions 0644, 0600 suggested.
[root@stone ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 2097148 0 -2
/root/swap file 1048572 0 -3
- 添加到
/etc/fstab
文件中
[root@stone ~]# vi /etc/fstab
#
# /etc/fstab
# Created by anaconda on Thu Jun 22 20:37:31 2023
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=68090631-9520-495e-a71d-b4e712110509 /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/dev/sdb1 /data/sdb1/ xfs defaults 0 0
/root/swap swap swap defaults 0 0
- 可以使用
swapoff
命令禁用/root/swap
,然后使用swapon -a
命令挂载/etc/fstab
文件中的 “swap” 文件系统
[root@stone ~]# swapoff /root/swap
[root@stone ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 2097148 0 -2
[root@stone ~]# swapon -a
swapon: /root/swap: insecure permissions 0644, 0600 suggested.
[root@stone ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 2097148 0 -2
/root/swap file 1048572 0 -3
进程
执行文件系统上的程序后,系统会将其读入到内存中,作为进程来运行。
进程管理
在 Windows 上,可以通过任务管理器图像界面来管理进程,而在 Linux 上,一般通过命令来进行管理。
ps
使用 ps
(process status)命令查看进程快照信息。
常用选项有:
-l
:查看当前 Shell 的进程aux
:查看所有进程,包括进程使用的 CPU,内存等信息-ef
:查看所有进程,包括父进程 PID-u
:指定查看某个用户的进程
查看当前 Shell 的进程:
[root@stone ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 6790 6788 0 80 0 - 28984 do_wai pts/1 00:00:00 bash
0 R 0 9380 6790 0 80 0 - 38337 - pts/1 00:00:00 ps
其中:
F
:标志位,4
表示根程序,0
表示子程序S
:进程状态,S
表示睡眠中(Sleep),R
表示运行中(Running),T
表示停止(Stop),Z
表示僵死(Zombie)UID
:用户 ID(User ID)PID
:进程 ID(Process ID)PPID
:进程父 ID(Parent Process ID)C
:CPU 使用率PRI
:CPU 优先级(Priority),越小优先级越高,用户无法调整NI
:表示 Nice,用于调整PRI
,范围为 -20 ~ 19ADDR
:内存位置,一般为-
SZ
:使用的内存大小WCHAN
:进程是否在运行,如果在运行,则为-
TTY
:登录终端TIME
:占用 CPU 时间CMD
:执行的命令
查看所有进程:
[root@stone ~]# ps aux | head -5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 191056 3952 ? Ss 10:50 0:09 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 10:50 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 10:50 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S 10:50 0:01 [ksoftirqd/0]
其中:
USER
:运行进程的用户名称PID
:进程 ID%CPU
:进程占用的 CPU 百分比%MEM
:进程占用的内存百分比VSZ
:分配给进程的虚拟内存大小(Virtual Memory Size),以 KB 为单位RSS
:进程使用的物理内存大小(Resident Set Size),以 KB 为单位TTY
:登录终端STAT
:进程状态S
:睡眠中(Sleep)s
:父进程<
:优先级高的进程R
:运行中(Running)T
:停止(Stop)Z
:僵死(Zombie)D
:不可中断,通常处于等待 I/ON
:优先级低的进程l
:包含多个线程+
:进程位于前台
START
:进程开始时间TIME
:占用 CPU 时间COMMAND
:执行的命令
查看所有进程:
[root@stone ~]# ps -ef | head -5
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 10:50 ? 00:00:09 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0 0 10:50 ? 00:00:00 [kthreadd]
root 4 2 0 10:50 ? 00:00:00 [kworker/0:0H]
root 6 2 0 10:50 ? 00:00:01 [ksoftirqd/0]
其中:
UID
:用户 IDPID
:进程 IDPPID
:进程父 IDC
:CPU 使用率STIME
:进程开始时间TTY
:登录终端TIME
:占用 CPU 时间CMD
:执行的命令
查看某个用户的进程:
[root@stone ~]# ps -u mysql
PID TTY TIME CMD
1414 ? 00:11:14 mysqld
查看线程:
[root@stone ~]# ps -eLf | egrep '(PID|mysqld)' | head -5
UID PID PPID LWP C NLWP STIME TTY TIME CMD
mysql 1414 1 1414 0 68 10:50 ? 00:00:02 /usr/sbin/mysqld
mysql 1414 1 1425 0 68 10:50 ? 00:00:01 /usr/sbin/mysqld
mysql 1414 1 1426 0 68 10:50 ? 00:00:01 /usr/sbin/mysqld
mysql 1414 1 1427 0 68 10:50 ? 00:00:01 /usr/sbin/mysqld
[root@stone ~]# ps -T -p `pgrep mysqld`
PID SPID TTY TIME CMD
17478 17478 ? 00:00:21 mysqld
17478 17489 ? 00:20:23 ib_io_ibuf
17478 17490 ? 00:20:32 ib_io_log
17478 17491 ? 00:20:39 ib_io_rd-1
17478 17492 ? 00:20:41 ib_io_rd-2
17478 17493 ? 00:20:44 ib_io_rd-3
17478 17494 ? 00:20:38 ib_io_rd-4
17478 17495 ? 00:41:02 ib_io_wr-1
17478 17496 ? 00:40:49 ib_io_wr-2
17478 17497 ? 00:40:51 ib_io_wr-3
17478 17498 ? 00:40:48 ib_io_wr-4
17478 17499 ? 02:15:02 ib_pg_flush_co
17478 17500 ? 00:03:58 ib_pg_flush-1
17478 17501 ? 00:03:59 ib_pg_flush-2
17478 17502 ? 00:03:59 ib_pg_flush-3
17478 17503 ? 00:57:34 ib_log_checkpt
17478 17504 ? 02:50:27 ib_log_fl_notif
17478 17505 ? 04:29:54 ib_log_flush
17478 17506 ? 02:39:49 ib_log_wr_notif
17478 17507 ? 03:45:43 ib_log_writer
17478 17508 ? 18:04:09 ib_log_files_g
17478 17513 ? 00:12:21 ib_srv_lock_to
17478 17514 ? 00:12:28 ib_srv_err_mon
17478 17515 ? 00:01:07 ib_srv_mon
17478 17516 ? 00:00:00 ib_buf_resize
17478 17517 ? 00:49:07 ib_src_main
17478 17518 ? 00:01:10 ib_dict_stats
17478 17519 ? 00:02:34 ib_fts_opt
17478 17520 ? 00:00:11 xpl_worker-1
17478 17521 ? 00:00:11 xpl_worker-2
17478 17526 ? 00:00:00 ib_buf_dump
17478 17527 ? 03:12:27 ib_clone_gtid
17478 17528 ? 01:27:17 ib_srv_purge
17478 17529 ? 00:25:05 ib_srv_wkr-1
17478 17530 ? 00:18:46 ib_srv_wkr-2
17478 17531 ? 00:16:40 ib_srv_wkr-3
17478 17532 ? 00:00:00 evt_sched
17478 17533 ? 00:00:00 sig_handler
17478 17534 ? 00:00:00 xpl_accept-3
17478 17535 ? 00:14:59 xpl_accept-2
17478 17536 ? 00:00:00 gtid_zip
17478 17540 ? 00:13:55 connection
其中:
UID
:用户 IDPID
:进程 IDPPID
:进程父 IDLWP
:线程 ID(Light Weight Process)C
:CPU 使用率NLWP
:线程数据(Number of Light Weight Process)STIME
:进程开始时间TTY
:登录终端TIME
:占用 CPU 时间CMD
:执行的命令
查看进程树:
[root@stone ~]# ps axjf | egrep '(PID|httpd)' | grep -v grep
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
1 1013 1013 1013 ? -1 Ss 0 0:01 /usr/sbin/httpd -DFOREGROUND
1013 1058 1013 1013 ? -1 S 48 0:00 \_ /usr/sbin/httpd -DFOREGROUND
1013 1059 1013 1013 ? -1 S 48 0:00 \_ /usr/sbin/httpd -DFOREGROUND
1013 1060 1013 1013 ? -1 S 48 0:00 \_ /usr/sbin/httpd -DFOREGROUND
1013 1062 1013 1013 ? -1 S 48 0:00 \_ /usr/sbin/httpd -DFOREGROUND
1013 1063 1013 1013 ? -1 S 48 0:00 \_ /usr/sbin/httpd -DFOREGROUND
其中:
PPID
:进程父 IDPID
:进程 IDPGID
:进程组 ID( Process Group ID)SID
:会话 ID(Session ID)TTY
:登录终端TPGID
:终端上的前台进程组 ID(Foreground Process Group ID),后台运行的进程为-1
STAT
:进程状态UID
:用户 IDTIME
:占用 CPU 时间COMMAND
:执行的命令
pstree
使用 pstree
命令以树状显示进程信息。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install psmisc
常用选项有:
-p
:显示 PID-u
:显示 用户名称
查看所有进程,以树状显示:
[root@stone ~]# pstree
systemd─┬─agetty
├─auditd───{auditd}
├─chronyd
├─containerd───10*[{containerd}]
├─crond
├─dbus-daemon
├─dockerd───10*[{dockerd}]
├─gssproxy───5*[{gssproxy}]
├─httpd───5*[httpd]
├─irqbalance
├─lvmetad
├─mysqld───67*[{mysqld}]
├─mysqlrouter───24*[{mysqlrouter}]
├─php-fpm───10*[php-fpm]
├─polkitd───6*[{polkitd}]
├─rpcbind
├─rsyslogd───2*[{rsyslogd}]
├─sshd─┬─sshd───bash───man───less
│ ├─sshd───bash───pstree
│ └─sshd───bash
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───4*[{tuned}]
├─zabbix_agentd───5*[zabbix_agentd]
└─zabbix_server───37*[zabbix_server]
查看指定父进程,以树状显示,并显示 PID:
[root@stone ~]# pstree 1007 -p
sshd(1007)─┬─sshd(1647)───bash(1649)───man(12010)───less(12020)
├─sshd(6788)───bash(6790)───pstree(12773)
└─sshd(6808)───bash(6810)
查看指定父进程,以树状显示,并显示 PID 和用户名称:
[root@stone ~]# pstree 1013 -p -u
httpd(1013)─┬─httpd(1058,apache)
├─httpd(1059,apache)
├─httpd(1060,apache)
├─httpd(1062,apache)
└─httpd(1063,apache)
top
使用 top
命令实时查看系统信息,包括内存,CPU以及进程信息。类似于 Windows 的任务管理器。
常用选项有:
-d
:指定刷新时间间隔,以秒为单位,默认 3 秒-b
:以批处理方式运行,将信息重定向到文件-n
:一般配合-b
,表示获取n
次数据后退出-p
:指定监控的进程 ID-u
:指定用户名称-H
:显示线程
查看系统所有进程运行情况:
[root@stone ~]# top
top - 13:31:34 up 2 min, 2 users, load average: 0.22, 0.19, 0.08
Tasks: 261 total, 1 running, 260 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 1.2 sy, 0.0 ni, 98.1 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4026164 total, 1668192 free, 1861012 used, 496960 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 1929864 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1409 mysql 20 0 2867028 491500 21920 S 4.0 12.2 0:07.80 mysqld
769 dbus 20 0 58112 2320 1784 S 0.7 0.1 0:00.09 dbus-daemon
1034 zabbix 20 0 78892 2436 1508 S 0.7 0.1 0:00.04 zabbix_agentd
1 root 20 0 125524 3968 2568 S 0.3 0.1 0:01.36 systemd
594 root 20 0 0 0 0 S 0.3 0.0 0:00.07 kworker/1:3
1017 root 20 0 372220 41292 15296 S 0.3 1.0 0:01.07 containerd
1031 zabbix 20 0 78772 1360 576 S 0.3 0.0 0:00.05 zabbix_agentd
1032 zabbix 20 0 78892 2412 1484 S 0.3 0.1 0:00.08 zabbix_agentd
1592 mysqlro+ 20 0 1265880 16628 7236 S 0.3 0.4 0:00.34 mysqlrouter
......
其中:
第 1 行与
uptime
命令的输出类似,包括:13:31:34
:表示当前时间up 2 min
:表示启动了 2 分钟2 users
:表示有 2 个用户登录到系统load average: 0.22, 0.19, 0.08
:表示系统在 1,5,15 分钟内的平均负载
第 2 行显示总进程数量与各状态数量,包括 running,sleeping,stopped,zombie
第 3 行显示各类型负载占 CPU 百分比,包括:
us
:没有修改优先级的用户进程sy
:内核进程ni
:修改了优先级的用户进程id
:闲置状态wa
:等待 I/O 完成hi
:硬件中断si
:软件中断st
:虚拟机
第 4 行显示物理内存使用情况,与
free -k
命令的输出类似,为/proc/meminfo
的相关内容项,包括:total
:总内存,为/proc/meminfo
中的MemTotal
free
:未使用内存,为/proc/meminfo
中的MemFree
used
:已用内存,为total - free - buffers - cache
buff/cache
:buff
是内核缓冲(kernel buffers),为/proc/meminfo
中的Buffers
;cache
是页面缓存(page cache)和 slabs,为/proc/meminfo
中的Cached
和SReclaimable
第 5 行显示 SWAP 使用情况,包括:
total
:总 SWAP,为/proc/meminfo
中的SwapTotal
free
:未使用 SWAP,为/proc/meminfo
中的SwapFree
used
:已用 SWAP,为total - free
avail Mem
:可用物理内存,为/proc/meminfo
中的MemAvailable
第 7 行及以下为进程信息,包括:
PID
:进程 IDUSER
:运行进程的用户名称PR
:CPU 优先级(Priority),越小优先级越高,用户无法调整NI
:表示 Nice,用于调整PRI
,范围为 -20 ~ 19VIRT
:分配给进程的虚拟内存大小(Virtual Memory Size),以 KB 为单位RES
:进程使用的物理内存大小(Resident Set Size),以 KB 为单位SHR
:进程使用的共享内存大小(Shared Memory Size),以 KB 为单位%CPU
:CPU 使用率,如果有多个 CPU,可以使用H
键切换。默认是按照 CPU 使用率排序,如果不是,使用P
键按照 CPU 使用率排序%MEM
:内存使用率,使用M
键按照内存排序TIME+
:进程启动以来使用的总的 CPU 时间COMMAND
:进程名称
查看 MySQL 各个线程运行情况:
[root@stone ~]# top -p 1409 -H
top - 14:35:56 up 1:06, 4 users, load average: 0.00, 0.05, 0.10
Threads: 68 total, 0 running, 68 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.9 us, 1.5 sy, 0.0 ni, 97.1 id, 0.5 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4026164 total, 1545580 free, 1911220 used, 569364 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 1878644 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1439 mysql 20 0 2869084 527500 22056 S 1.0 13.1 0:27.11 ib_log_files_g
1435 mysql 20 0 2869084 527500 22056 S 0.7 13.1 0:11.95 ib_log_fl_notif
1436 mysql 20 0 2869084 527500 22056 S 0.7 13.1 0:20.73 ib_log_flush
1438 mysql 20 0 2869084 527500 22056 S 0.7 13.1 0:14.07 ib_log_writer
1427 mysql 20 0 2869084 527500 22056 S 0.3 13.1 0:04.13 ib_io_wr-2
1429 mysql 20 0 2869084 527500 22056 S 0.3 13.1 0:04.34 ib_io_wr-4
......
进入 top
页面后,按下 h
获取帮助信息:
Help for Interactive Commands - procps-ng version 3.3.10
Window 1:Def: Cumulative mode Off. System: Delay 3.0 secs; Secure mode Off.
Z,B,E,e Global: 'Z' colors; 'B' bold; 'E'/'e' summary/task memory scale
l,t,m Toggle Summary: 'l' load avg; 't' task/cpu stats; 'm' memory info
0,1,2,3,I Toggle: '0' zeros; '1/2/3' cpus or numa node views; 'I' Irix mode
f,F,X Fields: 'f'/'F' add/remove/order/sort; 'X' increase fixed-width
L,&,<,> . Locate: 'L'/'&' find/again; Move sort column: '<'/'>' left/right
R,H,V,J . Toggle: 'R' Sort; 'H' Threads; 'V' Forest view; 'J' Num justify
c,i,S,j . Toggle: 'c' Cmd name/line; 'i' Idle; 'S' Time; 'j' Str justify
x,y . Toggle highlights: 'x' sort field; 'y' running tasks
z,b . Toggle: 'z' color/mono; 'b' bold/reverse (only if 'x' or 'y')
u,U,o,O . Filter by: 'u'/'U' effective/any user; 'o'/'O' other criteria
n,#,^O . Set: 'n'/'#' max tasks displayed; Show: Ctrl+'O' other filter(s)
C,... . Toggle scroll coordinates msg for: up,down,left,right,home,end
k,r Manipulate tasks: 'k' kill; 'r' renice
d or s Set update interval
W,Y Write configuration file 'W'; Inspect other output 'Y'
q Quit
( commands shown with '.' require a visible task display window )
Press 'h' or '?' for help with Windows,
Type 'q' or <Esc> to continue
其中:
0
:当某一项的值为0
时,是否显示1
:是否显示所有 CPU 的使用情况K
:杀掉指定进程r
:改变某个进程优先级q
:退出
kill
使用 kill
命令发送信号给进程号。
常用选项有:
-l
:列出信号编码和名称
查看信号编码和名称:
[root@stone ~]# 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
其中:
1) SIGHUP
:通知进程重新加载配置文件9) SIGKILL
:强制终止进程15) SIGTERM
:结束进程,默认值。会等待正在进行的工作完成后才结束,如果卡死了,则无法结束
在一个 Session 中启动一个命令:
[root@stone ~]# tail -10f /var/log/messages
在另一个 Session 找到该进程号,强制结束该进程:
[root@stone ~]# pidof tail
5999
[root@stone ~]# kill -9 5999
或者:
[root@stone ~]# kill -9 `pidof tail`
或者:
[root@stone ~]# kill -9 `ps -ef | grep tail | grep -v grep | awk '{print $2}'`
killall
使用 killall
命令发送信号给进程名称。
常用选项有:
-u
:发送信号给某个用户的所有进程-i
:交互操作,需用户确认-w
:等待进程结束后再返回-o
:发送信号给运行超过指定时间(Older)的进程,单位可以是 s(seconds),m(minutes),h(hours),d(days),w(weeks),M(Months),y(years)-y
:发送信号给运行小于指定时间(Younger)的进程,单位可以是 s(seconds),m(minutes),h(hours),d(days),w(weeks),M(Months),y(years)
结束某个进程:
[root@stone ~]# killall tail
强制结束某个用户的所有进程:
[root@stone ~]# ps -u stone
PID TTY TIME CMD
6676 pts/0 00:00:00 bash
6741 pts/0 00:00:00 tail
[root@stone ~]# killall -9 -u stone
[root@stone ~]# ps -u stone
PID TTY TIME CMD
[root@stone ~]#
nice
使用 nice
命令调整命令的优先级。
常用选项有:
-n
:指定调整值,默认为 10,调整后范围为 -20 ~ 19
[root@stone ~]# nice -n -5 tail -1f /var/log/messages &
[1] 7161
[root@stone ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1534 1532 0 80 0 - 29047 do_wai pts/0 00:00:00 bash
4 S 0 7161 1534 0 75 -5 - 27023 wait_w pts/0 00:00:00 tail
0 R 0 7162 1534 0 80 0 - 38337 - pts/0 00:00:00 ps
[root@stone ~]# kill -9 7161
[root@stone ~]# nice tail -1f /var/log/messages &
[1] 7244
[root@stone ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1534 1532 0 80 0 - 29047 do_wai pts/0 00:00:00 bash
0 S 0 7244 1534 0 90 10 - 27023 wait_w pts/0 00:00:00 tail
0 R 0 7248 1534 0 80 0 - 38337 - pts/0 00:00:00 ps
renice
使用 renice
命令调整正在运行命令的优先级。
[root@stone ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1534 1532 0 80 0 - 29047 do_wai pts/0 00:00:00 bash
0 S 0 7244 1534 0 90 10 - 27023 wait_w pts/0 00:00:00 tail
0 R 0 7248 1534 0 80 0 - 38337 - pts/0 00:00:00 ps
[root@stone ~]# renice -5 7244
7244 (process ID) old priority 10, new priority -5
[root@stone ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1534 1532 0 80 0 - 29047 do_wai pts/0 00:00:00 bash
0 S 0 7244 1534 0 75 -5 - 27023 wait_w pts/0 00:00:00 tail
0 R 0 7269 1534 0 80 0 - 38337 - pts/0 00:00:00 ps
fuser
使用 fuser
命令查找使用文件的进程。
常用选项有:
-u
:显示进程的用户名称-v
:显示进程的用户名称(USER),进程 ID(PID),访问类型(ACCESS)及命令(COMMAND),其中访问类型包括:c
:当前目录e
:正在运行的可执行文件f
:打开的文件F
:打开文件进行写入r
:根目录m
:映射文件或共享库
-m
:列出访问该文件所在文件系统的文件的所有进程,当使用umount
命令卸载某个文件系统时,如果提示target is busy
,使用该选项可以方便的找到与该文件系统相关的进程-k
:默认发送 SIGKILL 信号给找到的进程-i
:与-k
选项配合,需要用户进行确认
[root@stone ~]# fuser /var/log/messages
/var/log/messages: 1014
[root@stone ~]# fuser -u /var/log/messages
/var/log/messages: 1014(root)
[root@stone ~]# fuser -vu /var/log/messages
USER PID ACCESS COMMAND
/var/log/messages: root 1014 F.... (root)rsyslogd
pidof
使用 pidof
命令列出进程的 PID。
[root@stone ~]# pidof rsyslogd
1014
lsof
使用 lsof
(list open files)命令列出由进程打开的文件。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install lsof
常用选项有:
-p
:查看某个进程 ID 打开的文件-u
:查看某个用户名称打开的文件-i
:查看与某个网络地址匹配的文件,网络地址格式为:[46][protocol][@hostname|hostaddr][:service|port]
,其中:[46]
:IPv4 或者 IPv6[protocol]
:协议名称,TCP,UDP等[@hostname|hostaddr]
:主机名称或者地址[:service|port]
:服务名称(/etc/services)或者端口
+d
:列出指定目录下打开的文件+D
:列出指定目录及其子目录下打开的文件-t
:只列出进程 ID
执行以下命令:
[root@stone ~]# tail -1f /var/log/messages
Jul 27 14:19:26 stone systemd-logind: New session 43 of user root.
在另外的 Shell 环境查看进程打开的文件:
[root@stone ~]# lsof -p `pidof tail`
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
tail 21070 root cwd DIR 253,0 4096 67146817 /root
tail 21070 root rtd DIR 253,0 256 64 /
tail 21070 root txt REG 253,0 66824 100873306 /usr/bin/tail
tail 21070 root mem REG 253,0 106172832 100882464 /usr/lib/locale/locale-archive
tail 21070 root mem REG 253,0 2156240 12121 /usr/lib64/libc-2.17.so
tail 21070 root mem REG 253,0 163312 12114 /usr/lib64/ld-2.17.so
tail 21070 root 0u CHR 136,3 0t0 6 /dev/pts/3
tail 21070 root 1u CHR 136,3 0t0 6 /dev/pts/3
tail 21070 root 2u CHR 136,3 0t0 6 /dev/pts/3
tail 21070 root 3r REG 253,0 573448 34350300 /var/log/messages
tail 21070 root 4r a_inode 0,10 0 7512 inotify
其中:
FD
:文件描述符(File Descriptor),包括:cwd
:执行命令的当前目录(current working directory)rtd
:根目录(root directory)txt
:程序文件(program text)mem
:内存映射文件(memory-mapped file)0u
:0
表示标准输入,u
表示可读可写1u
:1
表示标准输出,u
表示可读可写2u
:2
表示标准错误,u
表示可读可写
TYPE
:文件类型,包括:DIR
:目录(directory)REG
:普通文件(regular file)CHR
:字符特殊文件(character special file),或者字符设备(character devices)
DEVICE
:设备编号,来自于/proc/devices
SIZE/OFF
:文件大小NODE
:节点编号(Inode)NAME
:文件名称
还可以查看打开文件的进程:
[root@stone ~]# lsof /var/log/messages
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1014 root 7w REG 253,0 573899 34350300 /var/log/messages
tail 21070 root 3r REG 253,0 573899 34350300 /var/log/messages
[root@stone ~]# lsof -t /var/log/messages
1014
21070
查看某个用户的进程:
[root@stone ~]# lsof -t -u stone
24307
查看在 22 端口上打开的文件:
[root@stone ~]# lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1013 root 3u IPv4 27295 0t0 TCP *:ssh (LISTEN)
sshd 1013 root 4u IPv6 27297 0t0 TCP *:ssh (LISTEN)
sshd 1589 root 3u IPv4 29149 0t0 TCP stone:ssh->192.168.44.1:49226 (ESTABLISHED)
sshd 7702 root 3u IPv4 120009 0t0 TCP stone:ssh->192.168.44.1:64953 (ESTABLISHED)
sshd 10885 root 3u IPv4 126210 0t0 TCP stone:ssh->192.168.44.1:51178 (ESTABLISHED)
sshd 21039 root 3u IPv4 147992 0t0 TCP stone:ssh->192.168.44.1:61072 (ESTABLISHED)
sshd 21596 root 3u IPv4 149581 0t0 TCP stone:ssh->192.168.44.1:61198 (ESTABLISHED)
查看指定目录下打开的文件及对应进程:
[root@stone ~]# lsof +d /root/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 1591 root cwd DIR 253,0 4096 67146817 /root
如果文件被误删除了,只要还有进程正在访问该文件,则可以使用 lsof
命令找到被误删除的文件并进行恢复,例如有以下文件:
[root@stone ~]# cp /var/log/messages messages
[root@stone ~]# tail -1f messages
Jul 27 15:20:01 stone systemd: Started Session 52 of user root.
在其他会话删除该文件:
[root@stone ~]# rm -fr messages
找到打开该文件的进程:
[root@stone ~]# lsof | grep message | grep delete
tail 25366 root 3r REG 253,0 574078 67153793 /root/messages (deleted)
可以看到进程 25366
打开了删除的文件,其文件描述符为 3r
,最后面的 (deleted)
表示被删除,此时可以将 /proc/25366/fd/3
复制到原文件即可:
[root@stone ~]# cp /proc/25366/fd/3 messages
工作管理
在实际工作中,往往会有如下需求:
- 在同一个 Shell 中,同时执行多个命令。
- 断开 Shell 后,命令继续运行,不会中断。
此时就需要对执行的命令进行工作(Job)管理。
&
使用 &
将命令放到 Shell 后台执行。
[root@stone ~]# find / -name mysql.sock > /tmp/find.txt 2>&1 &
[1] 3119
其中:
[1]
:工作编号3119
:进程号
待命令在后台执行完成后,会输出如下信息:
[root@stone ~]#
[1]+ Done find / -name mysql.sock > /tmp/find.txt 2>&1
表示编号为 1 的工作已完成。
Ctrl + z
使用 Ctrl + z
组合按键可以将正在执行的命令放入 Shell 后台并暂停执行。
例如在执行 tail -f
命令时可以按下 Ctrl + z
将其放入 Shell 后台并暂停执行:
[root@stone ~]# tail -1f /var/log/messages
Jul 27 09:20:01 stone systemd: Started Session 6 of user root.
^Z
[1]+ Stopped tail -1f /var/log/messages
其中
[1]
:工作编号Stopped
:暂停执行
jobs
使用 jobs
命令查看 Shell 后台的工作。
常用选项有:
-l
:列出额外的进程 ID-r
:仅列出运行的工作-s
:仅列出暂停的工作
[root@stone ~]# jobs -l
[1]+ 2953 Stopped tail -1f /var/log/messages
[root@stone ~]# find / -mmin -5 > /tmp/find.txt 2>&1 &
[2] 1994
[root@stone ~]# jobs
[1]+ Stopped tail -1f /var/log/messages
[2]- Running find / -mmin -5 > /tmp/find.txt 2>&1 &
fg
使用 fg
命令将 Shell 后台工作放到前台运行。
[root@stone ~]# fg %1
tail -1f /var/log/messages
其中:
1
:表示工作编号,%
可加可不加
bg
使用 bg
命令运行在 Shell 后台暂停的工作。
[root@stone ~]# fg 1
tail -1f /var/log/messages
^Z
[1]+ Stopped tail -1f /var/log/messages
[root@stone ~]# jobs -l
[1]+ 3173 Stopped tail -1f /var/log/messages
[root@stone ~]# bg 1
[1]+ tail -1f /var/log/messages &
[root@stone ~]# jobs
[1]+ Running tail -1f /var/log/messages &
此时要停止该工作,既可以使用 fg
命令将其放到前台,然后使用 Ctrl + C
结束,也可以使用 kill
命令。使用 kill
命令时,既可以指定进程 ID,也可以使用百分号加上工作编号。
[root@stone ~]# kill -9 %1
[root@stone ~]# jobs -l
[1]+ 3173 Killed tail -1f /var/log/messages
nohup
使用 nohup
(no hangup)配合 &
将命令放到系统后台执行。
如果只是使用 &
将命令放入到 Shell 后台执行,那么在离开 Shell 环境后,命令会被中断,要保持命令继续执行,需要使用 nohup
。
使用 nohup
将 sleep 300
(睡眠 300 秒)命令放到系统后台执行,可以指定输出重定向,如果不指定,会将输出写入到当前目录的 nohup.out
文件中:
[root@stone ~]# nohup sleep 300 > /tmp/sleep.log 2>&1 &
[1] 7418
[root@stone ~]# logout
使用 logout
命令离开 Shell 环境后,再重新登录到系统查看:
[root@stone ~]# ps -ef | grep sleep | grep -v grep
root 7418 1 0 10:37 ? 00:00:00 sleep 300
服务
与 Windows 类似,Linux 也有很多的服务,本节介绍如何管理 Linux 的服务。
简介
什么是服务呢?简而言之,服务就是系统为提供某些功能而在后台运行的一系列程序。从 CentOS 7 开始,systemd
取代了 SysV
作为默认的服务管理程序。相比 SysV
,systemd
相当复杂,有非常多的概念和命令,这里只介绍最常用的概念和命令,更详细的内容请参考官方文档。
下图为 systemd
的架构图,看看就好。
与 systemd
相关的目录和文件有很多,重点关注以下两个目录及其里面的文件:
/etc/systemd/system
:开机时会读取该目录下的配置文件,实际为软链接,指向/usr/lib/systemd/system/
目录下的文件。
[root@stone ~]# ll /etc/systemd/system
total 4
drwxr-xr-x. 2 root root 57 Jun 22 20:38 basic.target.wants
lrwxrwxrwx. 1 root root 41 Jun 22 20:37 dbus-org.fedoraproject.FirewallD1.service -> /usr/lib/systemd/system/firewalld.service
lrwxrwxrwx. 1 root root 57 Jun 22 20:37 dbus-org.freedesktop.nm-dispatcher.service -> /usr/lib/systemd/system/NetworkManager-dispatcher.service
lrwxrwxrwx. 1 root root 37 Jun 22 20:39 default.target -> /lib/systemd/system/multi-user.target
drwxr-xr-x. 2 root root 87 Jun 22 20:37 default.target.wants
drwxr-xr-x. 2 root root 32 Jun 22 20:37 getty.target.wants
drwxr-xr-x. 2 root root 35 Jun 22 20:37 local-fs.target.wants
drwxr-xr-x. 2 root root 4096 Jun 22 20:38 multi-user.target.wants
drwxr-xr-x. 2 root root 48 Jun 22 20:37 network-online.target.wants
drwxr-xr-x. 2 root root 29 Jun 22 20:37 sockets.target.wants
drwxr-xr-x. 2 root root 254 Jun 22 20:37 sysinit.target.wants
drwxr-xr-x. 2 root root 44 Jun 22 20:37 system-update.target.wants
[root@stone ~]# ll /etc/systemd/system/multi-user.target.wants/
total 0
lrwxrwxrwx. 1 root root 38 Jun 22 20:37 auditd.service -> /usr/lib/systemd/system/auditd.service
lrwxrwxrwx. 1 root root 37 Jun 22 20:37 crond.service -> /usr/lib/systemd/system/crond.service
lrwxrwxrwx. 1 root root 41 Jun 22 20:37 firewalld.service -> /usr/lib/systemd/system/firewalld.service
lrwxrwxrwx. 1 root root 42 Jun 22 20:38 irqbalance.service -> /usr/lib/systemd/system/irqbalance.service
lrwxrwxrwx. 1 root root 37 Jun 22 20:37 kdump.service -> /usr/lib/systemd/system/kdump.service
lrwxrwxrwx. 1 root root 46 Jun 22 20:37 NetworkManager.service -> /usr/lib/systemd/system/NetworkManager.service
lrwxrwxrwx. 1 root root 39 Jun 22 20:37 postfix.service -> /usr/lib/systemd/system/postfix.service
lrwxrwxrwx. 1 root root 40 Jun 22 20:37 remote-fs.target -> /usr/lib/systemd/system/remote-fs.target
lrwxrwxrwx. 1 root root 46 Jun 22 20:37 rhel-configure.service -> /usr/lib/systemd/system/rhel-configure.service
lrwxrwxrwx. 1 root root 39 Jun 22 20:38 rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
lrwxrwxrwx. 1 root root 36 Jun 22 20:37 sshd.service -> /usr/lib/systemd/system/sshd.service
lrwxrwxrwx. 1 root root 37 Jun 22 20:37 tuned.service -> /usr/lib/systemd/system/tuned.service
/usr/lib/systemd/system
:存放各种类型的服务配置文件。
[root@stone ~]# ll /usr/lib/systemd/system
total 800
-rw-r--r--. 1 root root 1384 Aug 8 2019 auditd.service
lrwxrwxrwx. 1 root root 14 Jun 22 20:37 autovt@.service -> getty@.service
-rw-r--r--. 1 root root 517 Oct 2 2020 basic.target
drwxr-xr-x. 2 root root 67 Jun 22 20:37 basic.target.wants
-r--r--r--. 1 root root 429 Oct 1 2020 blk-availability.service
-rw-r--r--. 1 root root 379 Oct 2 2020 bluetooth.target
-rw-r--r--. 1 root root 160 May 22 2020 brandbot.path
-rw-r--r--. 1 root root 116 May 22 2020 brandbot.service
-rw-r--r--. 1 root root 787 Oct 2 2020 console-getty.service
-rw-r--r--. 1 root root 749 Oct 2 2020 console-shell.service
-rw-r--r--. 1 root root 808 Oct 2 2020 container-getty@.service
-rw-r--r--. 1 root root 294 Oct 20 2020 cpupower.service
-rw-r--r--. 1 root root 318 Aug 9 2019 crond.service
......
Unit
Unit 是管理服务的基本单元,在 /usr/lib/systemd/system
目录下的文件就是各个 Unit 的配置文件。
systemd
中可用的 Unit 类型有 11 种,需要重点关注以下 2 种类型:
- Service:用于启动和控制守护进程(daemons),以
.service
为文件扩展名,最常见的 Unit。 - Target:对 Unit 进行分组,一个或多个其它类型 Unit 的集合,以
.target
为文件扩展名。
Service
对于 Service 类型,来看看其配置文件:
[root@stone ~]# cat /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
其中:
[Unit]
:定义 Unit 的基本信息,与 Unit 的类型无关,包括:Description
:简要的描述信息。Documentation
:参考文档。Before
:指定其它 Unit 对该 Unit 的依赖性,其它 Unit 需在该 Unit 启动后才能启动。After
:指定该 Unit 对其它 Unit 的依赖性,该 Unit 需在其它 Unit 启动后才能启动。Wants
:配置对其它 Unit 的弱依赖关系,即使指定 Unit 启动失败也不影响该 Unit 的启动,也不影响启动顺序。Requires
:与Wants
类似,但配置对其它 Unit 的强依赖关系,指定 Unit 启动失败会影响该 Unit 的启动。Conflicts
:指定冲突的 Unit。
[Service]
:指定服务及其相关进程的信息,只有 Service 类型的 Unit 才有此项,包括:Type
:配置进程启动类型,包括:simple
:默认值,执行ExecStart
指定的命令,启动主进程。exec
:与simple
类似,不同之处在于,只有在该服务的主服务进程执行完成之后,systemd
才会认为该服务启动完成。 其他后继单元必须一直阻塞到这个时间点之后才能继续启动。forking
:ExecStart
将以fork()
方式启动,此时父进程将会退出,子进程将成为主进程。oneshot
:与simple
类似,不同之处在于,只有在该服务的主服务进程退出之后,systemd
才会认为该服务启动完成,才会开始启动后续 Unit。 此种类型的服务通常需要设置RemainAfterExit
选项。当Type
与ExecStart
都没有设置时,oneshot
就是默认值。dbus
:与simple
类似,但会等待 D-Bus 信号后启动。notify
:与exec
类似,启动结束后会发出通知信号,然后再启动其他服务。idle
:与simple
类似,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合。
EnvironmentFile
:指定当前服务的环境变量文件。ExecStart
:指定启动进程时执行的命令。ExecReload
:指定当该服务被要求重新加载配置时所执行的命令。ExecStop
:指定停止服务时执行的命令。KillMode
:如何停止服务,包括:control-group
:默认值,当前控制组里面的所有子进程,都会被终止。mixed
:发送 SIGTERM 给主进程,发送 SIGKILL 给其他进程。process
:仅终止主进程。none
:仅停止服务,不终止进程。
Restart
:指定重启策略,包括no
(默认值),on-success
,on-failure
,on-abnormal
,on-watchdog
,on-abort
和always
,具体如下:
Restart settings/Exit causes no
always
on-success
on-failure
on-abnormal
on-abort
on-watchdog
Clean exit code or signal X X Unclean exit code X X Unclean signal X X X X Timeout X X X Watchdog X X X X RestartSec
:重启服务前等待的时间,默认为 100ms。
[Install]
:说明此 Unit 的安装信息,包括:WantedBy
:指定一个或多个 Target 类型 Unit,说明此 Unit 属于哪个 Target。
Target
前面提到 Target 就是一组 Unit,包含许多相关的 Unit 。启动某个 Target 时,systemd
就会启动里面所有的 Unit。
- 如果 Target 只包含一个 Unit,则只有一个对应的配置文件,没有对应的目录。例如名称为
hibernate.target
的 Target 只包含一个名称systemd-hibernate.service
的 Unit,该 Unit 位于/usr/lib/systemd/system/
目录下:
[root@stone ~]# ll /usr/lib/systemd/system/hibernate*
-rw-r--r--. 1 root root 447 Oct 2 2020 /usr/lib/systemd/system/hibernate.target
- 如果 Target 包含多个 Unit,除了配置文件外,还有对应的目录,存放该 Target 包含的 Unit 的软链接。例如名称为
multi-user.target
的 Target 包含了多个 Unit,则会有一个名称为multi-user.target.wants
的目录存放该 Target 包含的 Unit 的软链接:
[root@stone ~]# ll /usr/lib/systemd/system/multi-user.target*
-rw-r--r--. 1 root root 492 Oct 2 2020 /usr/lib/systemd/system/multi-user.target
/usr/lib/systemd/system/multi-user.target.wants:
total 0
lrwxrwxrwx. 1 root root 15 Jun 22 20:37 dbus.service -> ../dbus.service
lrwxrwxrwx. 1 root root 15 Jun 22 20:37 getty.target -> ../getty.target
lrwxrwxrwx. 1 root root 24 Jun 22 20:37 plymouth-quit.service -> ../plymouth-quit.service
lrwxrwxrwx. 1 root root 29 Jun 22 20:37 plymouth-quit-wait.service -> ../plymouth-quit-wait.service
lrwxrwxrwx. 1 root root 33 Jun 22 20:37 systemd-ask-password-wall.path -> ../systemd-ask-password-wall.path
lrwxrwxrwx. 1 root root 25 Jun 22 20:37 systemd-logind.service -> ../systemd-logind.service
lrwxrwxrwx. 1 root root 39 Jun 22 20:37 systemd-update-utmp-runlevel.service -> ../systemd-update-utmp-runlevel.service
lrwxrwxrwx. 1 root root 32 Jun 22 20:37 systemd-user-sessions.service -> ../systemd-user-sessions.service
将系统在不同的状态时需要运行的 Unit 分组为不同的 Target,systemd
就可以使用不同的 Target 将系统启动或者切换到对应的状态,类似于 CentOS 7 之前的 RunLevel。RunLevel 与 Target 的对应关系如下:
[root@stone ~]# ll /usr/lib/systemd/system/runlevel*.target
lrwxrwxrwx. 1 root root 15 Jun 22 20:37 /usr/lib/systemd/system/runlevel0.target -> poweroff.target
lrwxrwxrwx. 1 root root 13 Jun 22 20:37 /usr/lib/systemd/system/runlevel1.target -> rescue.target
lrwxrwxrwx. 1 root root 17 Jun 22 20:37 /usr/lib/systemd/system/runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Jun 22 20:37 /usr/lib/systemd/system/runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Jun 22 20:37 /usr/lib/systemd/system/runlevel4.target -> multi-user.target
lrwxrwxrwx. 1 root root 16 Jun 22 20:37 /usr/lib/systemd/system/runlevel5.target -> graphical.target
lrwxrwxrwx. 1 root root 13 Jun 22 20:37 /usr/lib/systemd/system/runlevel6.target -> reboot.target
Runlevel | Target | 说明 |
---|---|---|
0 | poweroff.target | 关闭系统 |
1 | rescue.target | 维护模式 |
2,3,4 | multi-user.target | 多用户,文字界面,默认 Target |
5 | graphical.target | 多用户,图形界面 |
6 | reboot.target | 重启系统 |
不同的是,RunLevel 是互斥的,不可能多个 RunLevel 同时启动,但是某些 Target 是可以同时启动的。例如上面的 multi-user.target
和 graphical.target
是可以同时启动的,通过启动或关闭这两个 Target 之间不同的 Unit,可以实现文字界面和图形界面的快速切换。
默认的启动 Target 由 /etc/systemd/system/default.target
文件指定,一般软连接到 multi-user.target
或者 graphical.target
:
[root@stone ~]# ll /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 37 Jun 22 20:39 /etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target
对于 Target 类型,来看看其配置文件:
[root@stone ~]# cat /usr/lib/systemd/system/multi-user.target
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
其中各项含义与 Service 配置文件一样。
命令
systemd
包含许多命令来管理 Unit 和系统,这里介绍最常用的。
systemctl
使用 systemctl
命令管理 Unit。
常用选项有:
-t
:指定 Unit 类型-a
:显示所有 Unit
常用 Unit 子命令有:
list-units
:列出加载的 Unitstart
:启动 Unitstop
:停止 Unitreload
:重载 Unitrestart
:重启 Unitstatus
:查看 Unit 状态is-active
:检查 Unit 是否 Activeis-failed
:检查 Unit 是否 Failedisolate
:在不同的 Target 之间切换kill
:发送信号给 Unitlist-dependencies
:列出 Unit 依赖cat
:查看 Unit 配置文件
常用 Unit 文件子命令:
list-unit-files
:列出安装的 Unit 文件enable
:配置 Unit 开机启动disable
:配置 Unit 开机不启动is-enabled
:查看是否开机启动edit
:编辑 Unit 配置文件get-default
:获取默认 Targetset-default
:设置默认 Target
常用管理器生命周期命令:
daemon-reload
:重载所有修改过的配置文件
常用系统命令:
is-system-running
:检查系统是否完全运行default
:进入系统默认模式rescue
:进入系统拯救模式emergency
:进入系统紧急模式halt
:关闭和停止系统poweroff
:关闭系统并断电reboot
:重启suspend
:挂起系统hibernate
:休眠
虽然 systemctl
有这么多的子命令,但用得最多的还是 Unit 管理的这几个子命令,具体如下:
任务 | 旧命令(CentOS 7) | 新命令(CentOS 7) |
---|---|---|
配置开机启动 | chkconfig --level 3 crond on | systemctl enable crond.service |
配置开机不启动 | chkconfig --level 3 crond off | systemctl disable crond.service |
查看 Unit 状态 | service crond status | systemctl status crond.service (服务详细信息) systemctl is-active crond.service (仅显示是否 Active) |
显示所有已启动 Unit | chkconfig --list | systemctl list-units --type=service |
启动 Unit | service crond start | systemctl start crond.service |
停止 Unit | service crond stop | systemctl stop crond.service |
重启 Unit | service crond restart | systemctl restart crond.service |
查看 Unit 状态:
[root@stone ~]# systemctl status crond.service
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2023-07-29 09:44:58 CST; 6h ago
Main PID: 771 (crond)
CGroup: /system.slice/crond.service
└─771 /usr/sbin/crond -n
Jul 29 09:44:58 stone systemd[1]: Started Command Scheduler.
Jul 29 09:44:58 stone crond[771]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 24% if used.)
Jul 29 09:44:58 stone crond[771]: (CRON) INFO (running with inotify support)
其中:
第 2 行的 /usr/lib/systemd/system/crond.service; enabled
表示配置文件及开机启动
第 3 行的 Active
表示运行状态,包括:
active (running)
:服务正在运行inactive (dead)
:服务已经停止
停止 Unit:
[root@stone ~]# systemctl stop crond.service
[root@stone ~]# systemctl status crond.service
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Sat 2023-07-29 16:35:37 CST; 8s ago
Process: 771 ExecStart=/usr/sbin/crond -n $CRONDARGS (code=exited, status=0/SUCCESS)
Main PID: 771 (code=exited, status=0/SUCCESS)
Jul 29 09:44:58 stone systemd[1]: Started Command Scheduler.
Jul 29 09:44:58 stone crond[771]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 24% if used.)
Jul 29 09:44:58 stone crond[771]: (CRON) INFO (running with inotify support)
Jul 29 16:35:37 stone systemd[1]: Stopping Command Scheduler...
Jul 29 16:35:37 stone systemd[1]: Stopped Command Scheduler.
开机启动设置:
[root@stone ~]# systemctl is-enabled crond.service
enabled
[root@stone ~]# systemctl disable crond.service
Removed symlink /etc/systemd/system/multi-user.target.wants/crond.service.
[root@stone ~]# systemctl is-enabled crond.service
disabled
[root@stone ~]# systemctl enable crond.service
Created symlink from /etc/systemd/system/multi-user.target.wants/crond.service to /usr/lib/systemd/system/crond.service.
可以看到,配置开机启动就是创建 /etc/systemd/system/multi-user.target.wants/crond.service
到 /usr/lib/systemd/system/crond.service
的软链接,配置开机不启动就是删除该软链接。
启动 Unit 或者重启 Unit:
[root@stone ~]# systemctl start crond.service
[root@stone ~]# systemctl restart crond.service
查看配置文件:
[root@stone ~]# systemctl cat crond.service
# /usr/lib/systemd/system/crond.service
[Unit]
Description=Command Scheduler
After=auditd.service systemd-user-sessions.service time-sync.target
[Service]
EnvironmentFile=/etc/sysconfig/crond
ExecStart=/usr/sbin/crond -n $CRONDARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=30s
[Install]
WantedBy=multi-user.target
修改配置文件后,需要重载配置文件才会生效:
[root@stone ~]# systemctl daemon-reload
journalctl
使用 journalctl
命令查看由 systemd
产生的日志。
常用选项有:
-u
:查看指定 Unit 的日志-f
:实时查看最新日志
[root@stone ~]# journalctl -u crond.service | tail -5
Jul 29 16:41:14 stone systemd[1]: Stopped Command Scheduler.
Jul 29 16:41:14 stone systemd[1]: Started Command Scheduler.
Jul 29 16:41:14 stone crond[2865]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 58% if used.)
Jul 29 16:41:14 stone crond[2865]: (CRON) INFO (running with inotify support)
Jul 29 16:41:14 stone crond[2865]: (CRON) INFO (@reboot jobs will be run at computer's startup.)
hostnamectl
使用 hostnamectl
命令管理主机名。
常用子命令有:
set-hostname
:设置主机名
查看主机名:
[root@stone ~]# hostnamectl
Static hostname: stone
Transient hostname: status
Icon name: computer-vm
Chassis: vm
Machine ID: d8f49d804904484184e0ccd2511cd4a4
Boot ID: 6a0c999d9ea443208c845b4b4b1aa5a8
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-1160.el7.x86_64
Architecture: x86-64
[root@stone ~]# cat /etc/hostname
stone
调整主机名:
[root@stone ~]# hostnamectl set-hostname stone1
[root@stone ~]# hostnamectl
Static hostname: stone1
Icon name: computer-vm
Chassis: vm
Machine ID: d8f49d804904484184e0ccd2511cd4a4
Boot ID: 6a0c999d9ea443208c845b4b4b1aa5a8
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-1160.el7.x86_64
Architecture: x86-64
[root@stone ~]# cat /etc/hostname
stone1
localectl
使用 localectl
命令管理本地化设置。
常用子命令有:
set-locale
:设置本地化参数
[root@stone ~]# localectl
System Locale: LANG=en_US.UTF-8
VC Keymap: us
X11 Layout: us
timedatectl
使用 timedatectl
命令管理系统时间和日期。
常用子命令有:
set-time
:设置系统时间set-timezone
:设置系统时区
[root@stone ~]# timedatectl
Local time: Sat 2023-07-29 17:57:42 CST
Universal time: Sat 2023-07-29 09:57:42 UTC
RTC time: Sat 2023-07-29 12:32:15
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: n/a
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
[root@stone ~]# timedatectl set-time 20:34:20
[root@stone ~]# timedatectl
Local time: Sat 2023-07-29 20:34:22 CST
Universal time: Sat 2023-07-29 12:34:22 UTC
RTC time: Sat 2023-07-29 12:34:23
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: n/a
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
loginctl
使用 loginctl
命令管理登录会话和用户。
常用子命令有:
list-sessions
:列出 Sessionterminate-session
:终止 Sessionkill-session
:发生信号给 Session 进程list-users
:列出用户terminate-user
:终止用户的所有 Sessionkill-user
:发送信号给用户的进程
[root@stone ~]# loginctl list-sessions
SESSION UID USER SEAT
1 0 root
2 0 root
2 sessions listed.
[root@stone ~]# loginctl list-users
UID USER
0 root
1 users listed.
任务
与 Windows 类似,Linux 也可以配置计划任务,本节介绍如何管理 Linux 的计划任务。
可以将计划任务分为两类:
- 单次执行:使用
atd
服务,在指定时间执行任务一次。 - 循环执行:使用
crond
服务,按照配置循环执行任务。
单次执行
在实际工作中,有时需要在未来的某个时间点执行某个命令或者脚本,可以使用 atd
服务的相关命令进行配置。
如果系统没有该服务,使用 YUM 进行安装:
[root@stone ~]# yum install at
安装后启动 atd
服务:
[root@stone ~]# systemctl start atd
[root@stone ~]# systemctl status atd
● atd.service - Job spooling tools
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-07-31 09:06:18 CST; 13s ago
Main PID: 1692 (atd)
Tasks: 1
Memory: 216.0K
CGroup: /system.slice/atd.service
└─1692 /usr/sbin/atd -f
Jul 31 09:06:18 stone systemd[1]: Started Job spooling tools.
at
使用 at
命令创建单次执行任务。
常用选项有:
-l
:列出还没有执行的单次任务,等效于命令atq
-r
:删除单次任务,等效于命令atrm
-c
:查看任务内容,实际上查看的是/var/spool/at/
目录下的文件
常用时间格式:
HH:MM YY-MM-DD
:未来的某个时间点now + N [minutes][hours][days][weeks]
:在现在时间的N
分钟,小时,天或周之后
使用交互模式配置单次任务:
[root@stone ~]# at 09:55 2023-07-31
at> free -m > /root/free.log
at> <EOT>
job 2 at Mon Jul 31 09:55:00 2023
[root@stone ~]# at -l
2 Mon Jul 31 09:55:00 2023 a root
[root@stone ~]# at -c 2
......
free -m > /root/free.log
......
其中:
09:55 2023-07-31
:为指定的时间点free -m > /root/free.log
:为任务内容<EOT>
:为按下组合键Ctrl + d
后退出交互模式
使用标准输入配置单次任务:
[root@stone ~]# echo "df -h > df.log" | at now +10 minutes
job 3 at Mon Jul 31 10:00:00 2023
[root@stone ~]# at -l
2 Mon Jul 31 09:55:00 2023 a root
3 Mon Jul 31 10:00:00 2023 a root
[root@stone ~]# at -c 3
......
df -h > df.log
......
删除任务:
[root@stone ~]# at -l
3 Mon Jul 31 10:00:00 2023 a root
[root@stone ~]# at -r 3
[root@stone ~]# at -l
[root@stone ~]#
循环执行
在实际工作中,经常需要每天或者每周循环执行某个命令或者脚本,可以使用 crond
服务的相关命令进行配置。
系统一般默认安装并启动了 crond
服务:
[root@stone ~]# systemctl status crond
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-07-31 09:02:10 CST; 1h 16min ago
Main PID: 800 (crond)
Tasks: 1
Memory: 748.0K
CGroup: /system.slice/crond.service
└─800 /usr/sbin/crond -n
Jul 31 09:02:10 stone systemd[1]: Started Command Scheduler.
Jul 31 09:02:10 stone crond[800]: (CRON) INFO (Syslog will be used instead of sendmail.)
Jul 31 09:02:10 stone crond[800]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 9% if used.)
Jul 31 09:02:10 stone crond[800]: (CRON) INFO (running with inotify support)
crontab
使用 crontab
命令创建循环执行任务。
常用选项有:
-l
:查看任务,实际上是查看/var/spool/cron
目录下对应的文件-e
:编辑任务,使用vi
编辑/var/spool/cron
目录下对应的文件
创建一个在每天 12:30 执行的任务:
[root@stone ~]# crontab -e
30 12 * * * df -h >> /root/df.log 2>&1
其中:
- 第 1 个字段表示分钟,0-59
- 第 2 个字段表示小时,0-23
- 第 3 个字段表示日期,1-31
- 第 4 个字段表示月份,1-12
- 第 5 个字段表示星期,0-7,0 和 7 都表示周日
- 第 6 个字段表示命令
常用的日期格式有:
*/5 * * * *
:表示每 5 分钟执行一次15 * * * *
:表示在每小时的 15 分钟时执行,如 00:15,01:15 等30 12 * * *
:表示在每天的 12:30 执行30 10,20 * * *
:表示在每天的 10:30 和 20:30 执行30 10-20 * * *
:表示在每天的 10 点到 20点的每小时的 30 分钟执行* 8-20/2 * * *
:表示在每天的 10 点到 20点每隔 2 小时执行一次30 12 1 * *
:表示在每月 1 号的 12:30 执行30 12 1 1 *
:表示在每年 1 月 1 号的 12:30 执行30 12 * * 6
:表示在每周 6 的 12:30 执行@reboot
:重启后执行@hourly
:每小时执行一次,等价于0 * * * *
@daily
:每天执行一次,等价于0 0 * * *
@monthly
:每月执行一次,等价于0 0 1 * *
@yearly
:每年执行一次,等价于0 0 1 1 *
@weekly
:每周执行一次,等价于0 0 * * 0
查看任务:
[root@stone ~]# crontab -l
30 12 * * * df -h >> /root/df.log 2>&1
[root@stone ~]# cat /var/spool/cron/root
30 12 * * * df -h >> /root/df.log 2>&1
可以从日志文件 /var/log/cron
查看执行情况。如果在任务执行过程中遇到找不到命令导致执行失败的问题,可以在脚本中读取环境变量文件,配置环境变量或者使用命令的绝对路径。
配置文件
除了使用 crontab
命令创建与业务相关的循环执行的任务外,还可以将系统相关的循环执行任务写入到 /etc/crontab
配置文件中:
[root@stone ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
其中,SHELL
,PATH
和 MAILTO
为环境变量,然后在最下面配置任务,格式与使用 crontab
命令类似,只是多了一个 user-name
字段,用来指定执行命令的用户。
除了在 /etc/crontab
文件中进行配置外,还可以针对特定的程序创建单独的循环执行任务配置文件,放到 /etc/cron.d
目录下:
[root@stone ~]# ll /etc/cron.d/
total 8
-rw-r--r--. 1 root root 128 Aug 9 2019 0hourly
-rw-------. 1 root root 235 Apr 1 2020 sysstat
[root@stone ~]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
对于文件 /etc/cron.d/0hourly
,最后一行表示在每小时的 1 分钟时使用 root
用户执行命令 run-parts /etc/cron.hourly
,run-parts
为一个 Shell 脚本,会在 5 分钟内一个随机时间点执行 /etc/cron.hourly
目录下的脚本。当前 /etc/cron.hourly
目录下的脚本为 0anacron
:
[root@stone ~]# ll /etc/cron.hourly/
total 4
-rwxr-xr-x. 1 root root 392 Aug 9 2019 0anacron
[root@stone ~]# cat /etc/cron.hourly/0anacron
#!/bin/sh
# Check whether 0anacron was run today already
if test -r /var/spool/anacron/cron.daily; then
day=`cat /var/spool/anacron/cron.daily`
fi
if [ `date +%Y%m%d` = "$day" ]; then
exit 0;
fi
# Do not run jobs when on battery power
if test -x /usr/bin/on_ac_power; then
/usr/bin/on_ac_power >/dev/null 2>&1
if test $? -eq 1; then
exit 0
fi
fi
/usr/sbin/anacron -s
脚本 /etc/cron.hourly/0anacron
先读取目录 /var/spool/anacron/
下的时间戳文件来判断当天是否已经执行 anacron
命令,如果时间戳文件中的时间与当前时间不一致,则执行命令 /usr/sbin/anacron -s
。
命令 anacron
会读取文件 /etc/anacrontab
中配置的计划任务并执行,-s
选项表示串行执行,前一个任务完成后才执行下一个:
[root@stone ~]# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
其中:
period in days
:表示执行周期,1
表示每天,7
表示每周,@monthly
表示每月delay in minutes
:延迟时间,避免同一时间执行导致资源争用job-identifier
:任务名称,用于日志文件command
:执行的命令,此处使用run-parts
命令分别执行/etc/cron.daily
,/etc/cron.weekly
和/etc/cron.monthly
目录下的文件
到这里可能会疑惑,为什么要额外使用 anacron
命令来处理每天,每周和每月的任务呢,这是由于如果直接使用 crond
来处理,如果当时系统处于宕机状态,待恢复启动后,已经过了设定的处理时间了,则 crond
就不会处理了,使用 anacron
就可以更加上次处理的时间戳来判断是否需要处理。
命令 anacron
会将执行时的时间戳写入到 /var/spool/anacron
目录下的文件中以便判断是否已经执行:
[root@stone ~]# more /var/spool/anacron/*
::::::::::::::
/var/spool/anacron/cron.daily
::::::::::::::
20230731
::::::::::::::
/var/spool/anacron/cron.monthly
::::::::::::::
20230704
::::::::::::::
/var/spool/anacron/cron.weekly
::::::::::::::
20230725
综上,系统处理循环任务的流程如下:
crond
服务每分钟读取一次/var/spool/cron/*
,/etc/cron.d/*
和/etc/crontab
文件,根据配置执行对应的任务- 执行到
/etc/cron.d/0hourly
时,会执行/etc/cron.hourly
目录下的脚本 - 执行到
/etc/cron.hourly/0anacron
时,会调用anacron
命令执行文件/etc/anacrontab
中配置的计划任务,包括/etc/cron.daily
,/etc/cron.weekly
和/etc/cron.monthly
目录下的文件
网络
在前面安装 CentOS 时,是自动获取 IP 地址的,但是在实际工作中,通常都会为 Linux 服务器配置一个固定的 IP 地址。本节介绍如何管理 Linux 的网络。
文件
可以通过图形界面,文字界面菜单或者直接修改配置文件的方式来配置网络,这里只介绍通过修改配置文件来配置网络。
网口配置文件
在 Linux 中,每个网口都有一个对应的配置文件,位于 /etc/sysconfig/network-scripts/
目录下,文件名为 ifcfg-INTERFACE_NAME
,如果是 CentOS 6,一般默认为 ifcfg-eth0
,如果是 CentOS 7,一般默认为 ifcfg-ens33
。
为 Linux 服务器配置固定 IP 的配置如下:
[root@stone ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
BOOTPROTO="none"
DEFROUTE="yes"
IPADDR=192.168.44.135
NETMASK=255.255.255.0
GATEWAY=192.168.44.2
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
UUID="96350fad-1ffc-4410-a068-5d13244affb7"
其中:
TYPE
:网口类型,一般为"Ethernet"
BOOTPROTO
:获取 IP 的方式。如果为dhcp
,表示自动获取 IP;如果为static
或者none
,表示需手动配置 IPDEFROUTE
:默认路由接口IPADDR
:IP 地址NETMASK
:掩码地址GATEWAY
:网关地址NAME
:GUI 中显示的接口名称DEVICE
:物理网口名称ONBOOT
:接口是否在启动时激活UUID
:网口的 UUID
更多配置项请参考:Setting Up Networking 或者文件 /usr/share/doc/initscripts-*/sysconfig.txt
域名解析文件
使用 /etc/resolv.conf
文件指定 DNS 服务器以解析域名。
[root@stone ~]# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
search localdomain
nameserver 192.168.44.2
其中:
search
:默认仅包含本地域名。表示如果指定的主机名没有解析到,则会加上该域名作为后缀再次解析nameserver
:DNS 服务器地址,最多指定 3 个。
更多配置项请参考:resolv.conf(5) — Linux manual page 或者 man 5 resolv.conf
主机名与 IP 映射文件
使用 /etc/hosts
文件指定主机名与 IP 的映射,相当于静态的 DNS 解析。
[root@stone ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.44.135 stone
其中:
192.168.44.135
:IP 地址stone
:主机名
一定要将本机的 IP 地址和主机名配置到该文件中。
更详细的配置说明请参考:hosts(5) — Linux manual page 或者 man 5 hosts
服务
系统默认启用 network
服务来运行网络:
[root@stone ~]# systemctl status network
● network.service - LSB: Bring up/down networking
Loaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled)
Active: active (exited) since Tue 2023-08-01 13:30:32 CST; 1h 54min ago
Docs: man:systemd-sysv-generator(8)
Process: 785 ExecStart=/etc/rc.d/init.d/network start (code=exited, status=0/SUCCESS)
Tasks: 0
Memory: 0B
Aug 01 13:30:27 stone systemd[1]: Starting LSB: Bring up/down networking...
Aug 01 13:30:28 stone network[785]: Bringing up loopback interface: [ OK ]
Aug 01 13:30:32 stone network[785]: Bringing up interface ens33: [ OK ]
Aug 01 13:30:32 stone systemd[1]: Started LSB: Bring up/down networking.
可以看到 network
不是原生的 systemd
服务,其启动还是调用的 /etc/rc.d/init.d/network start
命令。查看其开机启动的方法如下:
[root@stone ~]# systemctl enable network
network.service is not a native service, redirecting to /sbin/chkconfig.
Executing /sbin/chkconfig network on
[root@stone ~]# chkconfig --list network
Note: This output shows SysV services only and does not include native
systemd services. SysV configuration data might be overridden by native
systemd configuration.
If you want to list systemd services use 'systemctl list-unit-files'.
To see services enabled on particular target use
'systemctl list-dependencies [target]'.
network 0:off 1:off 2:on 3:on 4:on 5:on 6:off
修改完该配置文件后,需要重启 network
服务才能生效:
[root@stone ~]# systemctl restart network
另外还有一个 NetworkManager
服务,在生产环境中一般较少用到,建议关闭:
[root@stone ~]# systemctl stop NetworkManager
[root@stone ~]# systemctl disable NetworkManager
命令
修改以上配置文件后,除了服务,可以使用以下命令来管理网络。
ifconfig
使用 ifconfig
(interface configure)命令配置网络接口。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install net-tools
常用选项有:
-a
:列出所有网口mtu
:设置 MTUup
:启动网口down
:关闭网口
查看网口情况:
[root@stone ~]# ifconfig -v
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.44.135 netmask 255.255.255.0 broadcast 192.168.44.255
inet6 fe80::20c:29ff:feb7:db9b prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b7:db:9b txqueuelen 1000 (Ethernet)
RX packets 36005 bytes 45413634 (43.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13831 bytes 1464515 (1.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 41894 bytes 2529563 (2.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 41894 bytes 2529563 (2.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
可以看到 ens33
网口和环回口都处于 UP, 其中:
mtu
:最大传输单元(Maximum Transmission Unit)inet
:IPv4 地址inet6
:IPv6 地址ether
:MAC 地址txqueuelen
:传输队列长度RX
:接收包情况TX
:发送包情况
创建一个虚拟网口,并设定其 MTU:
[root@stone ~]# ifconfig ens33:0 192.168.44.136
[root@stone ~]# ifconfig ens33:0 mtu 9000
[root@stone ~]# ifconfig ens33:0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9000
inet 192.168.44.136 netmask 255.255.255.0 broadcast 192.168.44.255
ether 00:0c:29:b7:db:9b txqueuelen 1000 (Ethernet)
[root@stone ~]# ifconfig ens33:0 down
ifup ifdown
使用 ifup
或者 ifdown
命令启动或关闭在 /etc/sysconfig/network-scripts/
目录下的网口。
[root@stone ~]# ifdown ens33
[root@stone ~]# ifup ens33
注意:
不要在终端执行
ifdown
,否则无法连接到服务器。
route
使用 route
命令管理网关。
常用选项有:
-n
:不显示主机名,显示 IP 地址
查看路由表:
[root@stone ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.44.2 0.0.0.0 UG 0 0 0 ens33
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 ens33
192.168.44.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33
其中:
Destination
:目的地址Gateway
:网关地址,0.0.0.0
表示本机Genmask
:掩码Flags
:包括:U
:启动(Up)G
:需要使用网关转发(Gateway)
Iface
:网口
ip
使用 ip
命令管理网络。
语法:
ip [ OPTIONS ] OBJECT { COMMAND | help }
其中:
OPTIONS
包括:-h
:以易读单位显示-s
:显示统计数据-d
:以详细格式-br
:以简化格式
OBJECT
包括:address
:网口地址信息link
:网口信息route
:路由信息
COMMAND
与对象有关,包括:add
:增加delete
:删除set
:设置show
:显示
查看网口地址信息:
[root@stone ~]# ip -h -s address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
RX: bytes packets errors dropped overrun mcast
5.59M 92.6k 0 0 0 0
TX: bytes packets errors dropped carrier collsns
5.59M 92.6k 0 0 0 0
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:b7:db:9b brd ff:ff:ff:ff:ff:ff
inet 192.168.44.135/24 brd 192.168.44.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feb7:db9b/64 scope link
valid_lft forever preferred_lft forever
RX: bytes packets errors dropped overrun mcast
45.6M 37.9k 0 0 0 0
TX: bytes packets errors dropped carrier collsns
1.79M 15.0k 0 0 0 0
[root@stone ~]# ip -br address
lo UNKNOWN 127.0.0.1/8 ::1/128
ens33 UP 192.168.44.135/24 fe80::20c:29ff:feb7:db9b/64
查看网口信息:
[root@stone ~]# ip -br link
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
ens33 UP 00:0c:29:b7:db:9b <BROADCAST,MULTICAST,UP,LOWER_UP>
查看路由信息:
[root@stone ~]# ip route
default via 192.168.44.2 dev ens33
169.254.0.0/16 dev ens33 scope link metric 1002
192.168.44.0/24 dev ens33 proto kernel scope link src 192.168.44.135
ping
使用 ping
命令测试网络连通性。
常用选项有:
-c
:执行次数-w
:超时秒数
先使用本机 IP 地址,以测试是否正确配置网口并启动:
[root@stone ~]# ping -c 3 192.168.44.135
PING 192.168.44.135 (192.168.44.135) 56(84) bytes of data.
64 bytes from 192.168.44.135: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 192.168.44.135: icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from 192.168.44.135: icmp_seq=3 ttl=64 time=0.094 ms
--- 192.168.44.135 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.037/0.065/0.094/0.024 ms
再使用本机主机名,以测试是否正确配置主机名和 IP 映射文件:
[root@stone ~]# ping -c 3 stone
PING stone (192.168.44.135) 56(84) bytes of data.
64 bytes from stone (192.168.44.135): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from stone (192.168.44.135): icmp_seq=2 ttl=64 time=0.116 ms
64 bytes from stone (192.168.44.135): icmp_seq=3 ttl=64 time=0.093 ms
--- stone ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.044/0.084/0.116/0.030 ms
再使用网关地址,以测试到网关的连通性:
[root@stone ~]# ping -c 3 192.168.44.2
PING 192.168.44.2 (192.168.44.2) 56(84) bytes of data.
64 bytes from 192.168.44.2: icmp_seq=1 ttl=128 time=0.158 ms
64 bytes from 192.168.44.2: icmp_seq=2 ttl=128 time=0.226 ms
64 bytes from 192.168.44.2: icmp_seq=3 ttl=128 time=0.378 ms
--- 192.168.44.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.158/0.254/0.378/0.091 ms
最后使用公网域名,以测试公网连通性及 DNS 是否配置正确:
[root@stone ~]# ping -c 3 www.baidu.com
PING www.a.shifen.com (14.119.104.189) 56(84) bytes of data.
64 bytes from 14.119.104.189 (14.119.104.189): icmp_seq=1 ttl=128 time=35.5 ms
64 bytes from 14.119.104.189 (14.119.104.189): icmp_seq=2 ttl=128 time=33.0 ms
64 bytes from 14.119.104.189 (14.119.104.189): icmp_seq=3 ttl=128 time=33.2 ms
--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 33.095/33.967/35.537/1.122 ms
traceroute
使用 traceroute
命令跟踪从源地址到目的地址之间的节点情况。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install traceroute
常用选项有:
-n
:不解析主机名,使用 IP 地址-w
:超时秒数,默认 5 秒-T
:使用 TCP
[root@stone ~]# traceroute -n -T www.baidu.com
traceroute to www.baidu.com (14.119.104.189), 30 hops max, 60 byte packets
1 192.168.44.2 0.247 ms 0.109 ms 0.072 ms
2 14.119.104.189 39.220 ms 45.048 ms 40.654 ms
netstat
使用 netstat
命令查看网络连接情况。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install net-tools
常用选项有:
-t
:列出使用 TCP 的连接-u
:列出使用 UDP 的连接-n
:不解析主机名,使用 IP 地址-a
:列出所有状态的连接-l
:仅列出监听状态的连接-p
:列出连接对应 PID 及进程名称-r
:列出路由表-i
:列出网口情况-s
:列出各协议的统计信息-c
:执行连续显示的间隔秒数
列出主机当前网络连接情况:
[root@stone ~]# netstat -tunap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:10051 0.0.0.0:* LISTEN 1449/zabbix_server
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 1009/php-fpm: maste
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 758/rpcbind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1007/sshd
tcp 0 0 0.0.0.0:10050 0.0.0.0:* LISTEN 1029/zabbix_agentd
tcp 0 0 127.0.0.1:10050 127.0.0.1:44174 TIME_WAIT -
......
tcp 0 96 192.168.44.135:22 192.168.44.1:50404 ESTABLISHED 1700/sshd: root@pts
tcp 0 0 127.0.0.1:10050 127.0.0.1:44218 TIME_WAIT -
......
tcp 0 0 192.168.44.135:22 192.168.44.1:50221 ESTABLISHED 1542/sshd: root@pts
tcp 0 0 127.0.0.1:10050 127.0.0.1:44146 TIME_WAIT -
tcp 0 0 127.0.0.1:10050 127.0.0.1:44188 TIME_WAIT -
tcp6 0 0 :::10051 :::* LISTEN 1449/zabbix_server
tcp6 0 0 :::33060 :::* LISTEN 1389/mysqld
tcp6 0 0 :::3306 :::* LISTEN 1389/mysqld
tcp6 0 0 :::111 :::* LISTEN 758/rpcbind
tcp6 0 0 :::80 :::* LISTEN 1011/httpd
tcp6 0 0 :::22 :::* LISTEN 1007/sshd
tcp6 0 0 :::10050 :::* LISTEN 1029/zabbix_agentd
udp 0 0 0.0.0.0:111 0.0.0.0:* 758/rpcbind
udp 0 0 127.0.0.1:323 0.0.0.0:* 768/chronyd
udp 0 0 0.0.0.0:932 0.0.0.0:* 758/rpcbind
udp6 0 0 :::111 :::* 758/rpcbind
udp6 0 0 ::1:323 :::* 768/chronyd
udp6 0 0 :::932 :::* 758/rpcbind
其中:
Proto
:协议Local Address
:本机地址和端口Foreign Address
:外部地址和端口State
:套接字状态,包括:LISTEN
:监听状态ESTABLISHED
:已建立连接TIME_WAIT
:套接字在关闭后等待处理仍在网络中的数据包CLOSE_WAIT
:外部连接已断开,等待套接字关闭
PID/Program name
:进程 PID 及名称
查看路由表:
[root@stone ~]# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.44.2 0.0.0.0 UG 0 0 0 ens33
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 ens33
192.168.44.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33
查看网口情况:
[root@stone ~]# netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
ens33 1500 2041 0 0 0 1487 0 0 0 BMRU
lo 65536 26605 0 0 0 26605 0 0 0 LRU
查看各协议统计信息:
[root@stone ~]# netstat -s
Ip:
28768 total packets received
0 forwarded
0 incoming packets discarded
28768 incoming packets delivered
28201 requests sent out
24 dropped because of missing route
Icmp:
8 ICMP messages received
3 input ICMP message failed.
ICMP input histogram:
timeout in transit: 6
echo replies: 2
18 ICMP messages sent
0 ICMP messages failed
ICMP output histogram:
destination unreachable: 9
echo request: 9
IcmpMsg:
InType0: 2
InType11: 6
OutType3: 9
OutType8: 9
Tcp:
2690 active connections openings
2687 passive connection openings
1 failed connection attempts
0 connection resets received
2 connections established
28320 segments received
27838 segments send out
0 segments retransmited
0 bad segments received.
22 resets sent
Udp:
186 packets received
9 packets to unknown port received.
0 packet receive errors
373 packets sent
0 receive buffer errors
0 send buffer errors
UdpLite:
TcpExt:
2645 TCP sockets finished time wait in fast timer
5 delayed acks sent
2685 packets directly queued to recvmsg prequeue.
64999 bytes directly received in process context from prequeue
372 packet headers predicted
2684 packets header predicted and directly queued to user
11090 acknowledgments not containing data payload received
402 predicted acknowledgments
TCPRcvCoalesce: 5
TCPAutoCorking: 2
TCPOrigDataSent: 11649
IpExt:
InBcastPkts: 245
InOctets: 1889743
OutOctets: 1912616
InBcastOctets: 19865
InNoECTPkts: 28818
持续查看某个端口的连接情况:
[root@stone ~]# netstat -c 2 -tunlp | grep 80
tcp6 0 0 :::80 :::* LISTEN 1011/httpd
tcp6 0 0 :::80 :::* LISTEN 1011/httpd
telnet
使用 telnet
命令检查主机端口是否开启。
[root@stone ~]# telnet www.baidu.com 443
Trying 14.119.104.254...
Connected to www.baidu.com.
Escape character is '^]'.
quit
Connection closed by foreign host.
host
使用 host
命令查找主机名对应的 IP。
[root@stone ~]# host www.baidu.com
www.baidu.com is an alias for www.a.shifen.com.
www.a.shifen.com has address 14.119.104.189
www.a.shifen.com has address 14.119.104.254
默认使用 /etc/resolv.conf
中指定的 DNS 服务器进行查找,也可以指定额外的 DNS 服务器:
[root@stone ~]# host www.baidu.com 114.114.114.114
Using domain server:
Name: 114.114.114.114
Address: 114.114.114.114#53
Aliases:
www.baidu.com is an alias for www.a.shifen.com.
www.a.shifen.com has address 14.119.104.189
www.a.shifen.com has address 14.119.104.254
nslookup
使用 nslookup
命令查找主机名对应的 IP。
[root@stone ~]# nslookup www.baidu.com
Server: 192.168.44.2
Address: 192.168.44.2#53
Non-authoritative answer:
www.baidu.com canonical name = www.a.shifen.com.
Name: www.a.shifen.com
Address: 14.119.104.254
Name: www.a.shifen.com
Address: 14.119.104.189
wget
使用 wget
命令下载文件。
常用选项有:
-b
:后台下载-c
:断点续传-i
:下载文件中的多个链接--limit-rate
:限定速度-O
:下载另存为的文件名或标准输出-q
:关闭输出
[root@stone ~]# wget https://nginx.org/download/nginx-1.24.0.tar.gz
--2023-08-02 14:04:24-- https://nginx.org/download/nginx-1.24.0.tar.gz
Resolving nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5702::6, ...
Connecting to nginx.org (nginx.org)|3.125.197.172|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1112471 (1.1M) [application/octet-stream]
Saving to: ‘nginx-1.24.0.tar.gz’
100%[===============================================================================================>] 1,112,471 8.64KB/s in 1m 48s
2023-08-02 14:06:15 (10.0 KB/s) - ‘nginx-1.24.0.tar.gz’ saved [1112471/1112471]
如果文件较大,可以放入后台下载:
[root@stone ~]# wget -b https://wordpress.org/latest.zip
Continuing in background, pid 65237.
Output will be written to ‘wget-log’.
查看下载进度:
[root@stone ~]# tail -5f wget-log
23850K .......... .......... .......... .......... .......... 99% 484K 0s
23900K .......... .......... .... 100% 394M=50s
2023-08-02 14:11:54 (476 KB/s) - ‘latest.zip’ saved [24498824/24498824]
curl
使用 curl
(Client URL)命令发出网络请求,获取数据。
语法:
curl [options] [URL...]
常用选项有:
-o
:将服务器的回应保存成文件,等同于wget
命令-O
:将下载内容保存为与 URL 中最后相同文件名的文件中-C
:断点续转-s
:静默下载,不显示进度信息-S
:只输出错误信息,通常与-s
一起使用-L
:让 HTTP 请求跟随服务器的重定向,默认不跟随重定向-d
:用于发送 POST 请求的数据体--data-urlencode
:等同于-d
,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码-X
:指定 HTTP 请求的方法-e
:设置 HTTP 的标头Referer
,表示请求的来源-A
:指定客户端的用户代理标头,即User-Agent
-H
:添加 HTTP 请求的标头-I
:向服务器发出 HEAD 请求,将返回的 HTTP 标头打印出来-u
:设置服务器认证的用户名和密码--limit-rate
:限定下载速度-w
:定义在 HTTP 请求完成后的输出,使用格式字符串指定显示的信息,常用格式字符串有:%{http_code}
:响应码%{size_download}
:下载总大小%{size_upload}
:上传总大小%{time_total}
:请求总时间
下载文件:
[root@stone ~]# curl -C - -O http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-7
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1690 100 1690 0 0 4936 0 --:--:-- --:--:-- --:--:-- 4941
[root@stone ~]# ll RPM-GPG-KEY-CentOS-7
-rw-r--r--. 1 root root 1690 Sep 1 13:55 RPM-GPG-KEY-CentOS-7
查看网站是否运行正常:
[root@stone ~]# curl -s -o /dev/null -w "%{http_code}" stonecoding.net
200
tcpdump
使用 tcpdump
命令抓包分析流量。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install tcpdump
常用选项有:
-A
:以 ASCII 显示-i
:指定网口-q
:简洁输出-w
:保存到指定文件-r
:读取由-w
保存的文件-c
:指定抓包的数量-nn
:不解析主机名,使用 IP 地址
抓取 10 个来自主机 192.168.44.1 通过网口 ens33 访问端口 80 的包:
[root@stone ~]# tcpdump -nn -i ens33 port 80 and src host 192.168.44.1 -c 10
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
14:54:49.997080 IP 192.168.44.1.60899 > 192.168.44.135.80: Flags [.], ack 1978136764, win 4106, length 0
14:54:54.987000 IP 192.168.44.1.60899 > 192.168.44.135.80: Flags [F.], seq 0, ack 1, win 4106, length 0
14:54:54.987502 IP 192.168.44.1.60903 > 192.168.44.135.80: Flags [S], seq 3584808811, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
14:54:54.988363 IP 192.168.44.1.60903 > 192.168.44.135.80: Flags [.], ack 2205435186, win 513, length 0
14:54:54.988851 IP 192.168.44.1.60903 > 192.168.44.135.80: Flags [P.], seq 0:715, ack 1, win 513, length 715: HTTP: POST /zabbix/jsrpc.php?output=json-rpc HTTP/1.1
14:54:55.104190 IP 192.168.44.1.60903 > 192.168.44.135.80: Flags [.], ack 632, win 510, length 0
14:54:57.301486 IP 192.168.44.1.60903 > 192.168.44.135.80: Flags [P.], seq 715:1548, ack 632, win 510, length 833: HTTP: POST /zabbix/zabbix.php?sid=93439db26486f4ef&action=hintbox.eventlist HTTP/1.1
14:54:57.479394 IP 192.168.44.1.60903 > 192.168.44.135.80: Flags [.], ack 2003, win 513, length 0
14:55:01.433780 IP 192.168.44.1.60909 > 192.168.44.135.80: Flags [S], seq 2022463334, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
14:55:01.434935 IP 192.168.44.1.60909 > 192.168.44.135.80: Flags [.], ack 2706327158, win 513, length 0
10 packets captured
10 packets received by filter
0 packets dropped by kernel
ethtool
使用 ethtool
命令查看网卡信息。
常用选项有:
-S
:查看网络使用情况
查看网卡信息:
[root@stone ~]# ethtool ens33
Settings for ens33:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: 1000Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
MDI-X: off (auto)
Supports Wake-on: d
Wake-on: d
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes
查看网络使用情况:
[root@stone ~]# ethtool -S ens33
NIC statistics:
rx_packets: 87
tx_packets: 74
rx_bytes: 10477
tx_bytes: 13078
rx_broadcast: 0
tx_broadcast: 0
rx_multicast: 0
tx_multicast: 0
rx_errors: 0
tx_errors: 0
tx_dropped: 0
multicast: 0
collisions: 0
rx_length_errors: 0
rx_over_errors: 0
rx_crc_errors: 0
rx_frame_errors: 0
rx_no_buffer_count: 0
rx_missed_errors: 0
tx_aborted_errors: 0
tx_carrier_errors: 0
tx_fifo_errors: 0
tx_heartbeat_errors: 0
tx_window_errors: 0
tx_abort_late_coll: 0
tx_deferred_ok: 0
tx_single_coll_ok: 0
tx_multi_coll_ok: 0
tx_timeout_count: 0
tx_restart_queue: 0
rx_long_length_errors: 0
rx_short_length_errors: 0
rx_align_errors: 0
tx_tcp_seg_good: 0
tx_tcp_seg_failed: 0
rx_flow_control_xon: 0
rx_flow_control_xoff: 0
tx_flow_control_xon: 0
tx_flow_control_xoff: 0
rx_long_byte_count: 10477
rx_csum_offload_good: 84
rx_csum_offload_errors: 0
alloc_rx_buff_failed: 0
tx_smbus: 0
rx_smbus: 0
dropped_smbus: 0
SSH
在前面连接到 CentOS 时,使用终端工具连接到 Linux,可以看到协议为 SSH。简单来说,SSH(Secure Shell)是一种网络协议,用于加密两台计算机之间的通信,保证远程登录和远程通信的安全。
SSH 协议的实现有多种,CentOS 默认使用 OpenSSH。SSH 架构为服务器-客户端模式,在这个架构中,SSH 软件分成两个部分:
- 服务器:接收客户端发出的请求的部分,OpenSSH 的实现为
sshd
- 客户端:向服务器发出请求的部分,OpenSSH 的实现为
ssh
服务器
OpenSSH 的服务端软件为 sshd
,默认以后台服务的形式运行,
[root@stone ~]# systemctl status sshd.service
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2023-09-01 13:26:18 CST; 2h 56min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1014 (sshd)
CGroup: /system.slice/sshd.service
└─1014 /usr/sbin/sshd -D
Sep 01 13:26:18 localhost.localdomain systemd[1]: Starting OpenSSH server daemon...
Sep 01 13:26:18 localhost.localdomain sshd[1014]: Server listening on 0.0.0.0 port 22.
Sep 01 13:26:18 localhost.localdomain sshd[1014]: Server listening on :: port 22.
Sep 01 13:26:18 localhost.localdomain systemd[1]: Started OpenSSH server daemon.
Sep 01 13:29:07 localhost.localdomain sshd[1899]: Accepted password for root from 192.168.92.1 port 56824 ssh2
Sep 01 13:29:26 stone sshd[1951]: Accepted password for root from 192.168.92.1 port 56839 ssh2
Sep 01 13:37:26 stone sshd[1991]: Accepted password for root from 192.168.92.1 port 57222 ssh2
Sep 01 16:14:35 stone sshd[9916]: Accepted password for root from 192.168.92.1 port 56629 ssh2
Sep 01 16:14:38 stone sshd[9936]: Accepted password for root from 192.168.92.1 port 56634 ssh2
配置文件为:/etc/ssh/sshd_config
。
[root@stone ~]# cat /etc/ssh/sshd_config
# $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several
# problems.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation sandbox
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
其中:
Port
:指定sshd
监听的端口,即客户端连接的端口,默认是 22PasswordAuthentication
:指定是否允许密码登录,默认值为yes
PermitEmptyPasswords
:指定是否允许空密码登录,默认为yes
PermitRootLogin
:指定是否允许root
用户登录,默认为yes
PubkeyAuthentication
:指定是否允许公钥登录,默认值为yes
HostKey
:指定服务器的密钥MaxStartups
:指定允许同时并发的 SSH 连接数量。如果设为0
,表示没有限制。设为A:B:C
的形式,比如MaxStartups 10:30:100
,表示如果达到 10 个并发连接,后面的连接将有 30% 的概率被拒绝;如果达到 100 个并发连接,则后面的连接将 100% 被拒绝PrintLastLog
:指定是否打印上一次用户登录时间,默认值为yes
如果修改了该配置文件,建议使用 sshd -t
命令检查语法是否正确。
客户端
OpenSSH 的服务端软件为 ssh
,CentOS 默认安装该客户端。
使用 ssh
命令连接到远程 Linux 主机。
语法:
ssh [options] [user@]hostname [command]
常用选项有:
-p
:指定端口,默认端口为 22
连接到远程 Linux 主机:
[root@stone ~]# ssh 192.168.92.129
The authenticity of host '192.168.92.129 (192.168.92.129)' can't be established.
ECDSA key fingerprint is SHA256:RthpTxXcV7xYM68bBvWB7Rl9lfg/wjRhTXV2+omPJpY.
ECDSA key fingerprint is MD5:c7:9e:98:c3:7e:cb:a8:12:87:bf:fd:6b:a3:d8:84:aa.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.92.129' (ECDSA) to the list of known hosts.
root@192.168.92.129's password:
Last login: Fri Sep 1 20:42:02 2023 from 192.168.92.1
[root@zabbix ~]# logout
Connection to 192.168.92.129 closed.
第一次连接时会打印远程 Linux 主机的指纹并需要确认,指纹是远程 Linux 主机公钥的哈希值:
[root@zabbix ~]# ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub
256 SHA256:RthpTxXcV7xYM68bBvWB7Rl9lfg/wjRhTXV2+omPJpY no comment (ECDSA)
确认后会将其保存到 ~/.ssh/known_hosts
文件中,后续就不再需要确认了。
[root@stone ~]# cat ~/.ssh/known_hosts
192.168.92.129 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNcVtR8pweYrJh2HlGyjAaQ4K1p8R6G97sXDmF16mtqk2Z7lSByOjoeMORBTtC4e/rJfKXKAR8whPAv4+mEc6/Q=
如果远程 Linux 主机的公钥发生了变化,则需要执行以下命令将原来的公钥指纹从 ~/.ssh/known_hosts
文件删除:
[root@stone ~]# ssh-keygen -R 192.168.92.129
# Host 192.168.92.129 found: line 1
/root/.ssh/known_hosts updated.
Original contents retained as /root/.ssh/known_hosts.old
连接到远程 Linux 主机执行命令:
[root@stone ~]# ssh root@192.168.92.129 hostname
The authenticity of host '192.168.92.129 (192.168.92.129)' can't be established.
ECDSA key fingerprint is SHA256:RthpTxXcV7xYM68bBvWB7Rl9lfg/wjRhTXV2+omPJpY.
ECDSA key fingerprint is MD5:c7:9e:98:c3:7e:cb:a8:12:87:bf:fd:6b:a3:d8:84:aa.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.92.129' (ECDSA) to the list of known hosts.
root@192.168.92.129's password:
zabbix
SSH 客户端的全局配置文件是 /etc/ssh/ssh_config
:
[root@stone ~]# cat /etc/ssh/ssh_config
# $OpenBSD: ssh_config,v 1.30 2016/02/20 23:06:23 sobrado Exp $
# This is the ssh client system-wide configuration file. See
# ssh_config(5) for more information. This file provides defaults for
# users, and the values can be changed in per-user configuration files
# or on the command line.
# Configuration data is parsed as follows:
# 1. command line options
# 2. user-specific file
# 3. system-wide file
# Any configuration value is only changed the first time it is set.
# Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end.
# Site-wide defaults for some commonly used options. For a comprehensive
# list of available options, their meanings and defaults, please see the
# ssh_config(5) man page.
# Host *
# ForwardAgent no
# ForwardX11 no
# RhostsRSAAuthentication no
# RSAAuthentication yes
# PasswordAuthentication yes
# HostbasedAuthentication no
# GSSAPIAuthentication no
# GSSAPIDelegateCredentials no
# GSSAPIKeyExchange no
# GSSAPITrustDNS no
# BatchMode no
# CheckHostIP yes
# AddressFamily any
# ConnectTimeout 0
# StrictHostKeyChecking ask
# IdentityFile ~/.ssh/identity
# IdentityFile ~/.ssh/id_rsa
# IdentityFile ~/.ssh/id_dsa
# IdentityFile ~/.ssh/id_ecdsa
# IdentityFile ~/.ssh/id_ed25519
# Port 22
# Protocol 2
# Cipher 3des
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
# EscapeChar ~
# Tunnel no
# TunnelDevice any:any
# PermitLocalCommand no
# VisualHostKey no
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# RekeyLimit 1G 1h
#
# Uncomment this if you want to use .local domain
# Host *.local
# CheckHostIP no
Host *
GSSAPIAuthentication yes
# If this option is set to yes then remote X11 clients will have full access
# to the original X11 display. As virtually no X11 client supports the untrusted
# mode correctly we set this to yes.
ForwardX11Trusted yes
# Send locale-related environment variables
SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
SendEnv XMODIFIERS
密钥登录
SSH 默认采用密码登录,有时候会需要使用密钥配置免密码登录。
SSH 密钥登录采用非对称加密,配置步骤如下:
- 客户端使用
ssh-keygen
在某个用户下生成自己的公钥和私钥。
[root@stone ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Fwp8pnLRgBOmoAgVligCMSctakFi04rbBAsubmWgySc root@stone
The key's randomart image is:
+---[RSA 2048]----+
|@O*ooo. |
|&O++o. o |
|%== .+ + . |
|BE.+ * . . |
|++= . o S . |
|.o. o . |
|. |
| |
| |
+----[SHA256]-----+
这里使用默认的私钥文件名,不为私钥文件设定密码保护。生成的私钥为 ~/.ssh/id_rsa
,公钥为 ~/.ssh/id_rsa.pub
。
[root@stone ~]# ll /root/.ssh/
-rw-------. 1 root root 1675 Sep 2 19:50 id_rsa
-rw-r--r--. 1 root root 392 Sep 2 19:50 id_rsa.pub
- 客户端使用
ssh-copy-id
命令,自动将公钥拷贝到远程服务器的~/.ssh/authorized_keys
文件中。如果~/.ssh/authorized_keys
文件不存在,会自动创建该文件。
[root@stone ~]# ssh-copy-id root@192.168.92.129
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.92.129's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.92.129'"
and check to make sure that only the key(s) you wanted were added.
- 进行测试,测试连接到远程服务器就不再需要密码了。
[root@stone ~]# ssh root@192.168.92.129
Last login: Sat Sep 2 19:47:58 2023 from 192.168.92.1
[root@zabbix ~]#
客户端使用密钥访问远程服务器的过程如下:
- 客户端向服务器发起 SSH 登录的请求。
- 服务器收到客户端 SSH 登录的请求后,发送一些随机数据给客户端,要求客户端证明自己的身份。
- 客户端收到服务器发来的数据,使用私钥对数据进行签名,然后再发还给服务器。
- 服务器收到客户端发来的加密签名后,使用对应的公钥解密,然后跟原始数据比较。如果一致,就允许客户端登录。
命令
scp
使用 scp
(secure copy)命令在服务器之间拷贝数据。它的底层是 SSH 协议,默认端口是 22,相当于先使用 ssh
命令登录远程主机,然后再执行拷贝操作。
scp
主要用于以下三种复制操作。
- 本地复制到远程服务器。
- 远程服务器复制到本地。
- 两个远程服务器之间的复制。
语法:
scp [options] [[user@]host1:]file1 ... [[user@]host2:]file2
将源端一个或多个文件或目录复制到目标端,如果省略用户名,则为当前登录用户名,如果省略主机名,则为当前主机。
注意:
如果所要复制的文件,在目标位置已经存在同名文件,
scp
会在没有警告的情况下覆盖同名文件。
常用选项有:
-r
:以递归方式复制目录-l
:指定传输数据的带宽,单位为 Kbit/s-P
:指定连接到远程服务器的端口-p
:保留修改时间(modification time)、访问时间(access time)、权限(mode)等原文件信息-q
:静默模式
拷贝文件到远程服务器:
[root@stone ~]# scp dflog root@192.168.92.129:/root
dflog 100% 441 36.4KB/s 00:00
[root@stone ~]#
拷贝目录到远程服务器:
[root@stone ~]# scp -r d1 root@192.168.92.129:/root
f1 100% 12 1.9KB/s 00:00
f2 100% 13 1.2KB/s 00:00
f3 100% 25 16.1KB/s 00:00
拷贝目录下的文件到远程服务器:
[root@stone ~]# scp -r d1/* root@192.168.92.129:/root
f1 100% 12 19.7KB/s 00:00
f2 100% 13 23.6KB/s 00:00
f3 100% 25 29.2KB/s 00:00
拷贝远程服务器目录到本地:
[root@stone ~]# scp -r root@192.168.92.129:/root/d1 .
f1 100% 12 29.3KB/s 00:00
f2 100% 13 35.9KB/s 00:00
f3 100% 25 39.3KB/s 00:00
rsync
使用 rsync
(remote sync)命令进行文件同步。可以在本地与远程主机之间,或者两个本地目录之间同步文件。
如果系统没有这个命令,使用 YUM 进行安装,本地和远程主机都需要安装:
[root@stone ~]# yum -y install rsync
语法:
Local: rsync [OPTION...] SRC... [DEST]
Access via remote shell:
Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
Push: rsync [OPTION...] SRC... [USER@]HOST:DEST
将源端一个或多个文件或目录同步到目标端,如果省略用户名,则为当前登录用户名,如果省略主机名,则为当前主机。
常用选项有:
-r
:以递归方式复制目录-a
:等效于-rlptgoD
,比-r
更常用,同步文件元数据-l
:等价于--links
,复制符号链接为符号链接-p
:保留权限-t
:保留修改时间-g
:保留属组-o
:保留用户-D
:等价于--devices --specials
,保留设备文件及特殊文件-n
:等价于--dry-run
,模拟运行-v
:输出信息-z
:等价于--compress
,传输时压缩文件--delete
:删除只存在于目标目录、不存在于源目录的文件,保存目录目录和源目录一致--existing
:不同步目标目录中不存在的文件--ignore-existing
:不同步目标目录已存在的文件--exclude
:排除指定文件--include
:包括指定文件--progress
:显示进度--stats
:显示文件传输状态
同步目录到远程主机,先模拟一下,没有问题再运行:
[root@stone ~]# rsync -anv --compress --stats d1 root@192.168.92.129:/root
sending incremental file list
d1/
d1/f1
d1/f2
d1/f3
Number of files: 4 (reg: 3, dir: 1)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 3
Total file size: 50 bytes
Total transferred file size: 50 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 114
Total bytes received: 29
sent 114 bytes received 29 bytes 286.00 bytes/sec
total size is 50 speedup is 0.35 (DRY RUN)
[root@stone ~]# rsync -av --compress --stats d1 root@192.168.92.129:/root
sending incremental file list
d1/
d1/f1
d1/f2
d1/f3
Number of files: 4 (reg: 3, dir: 1)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 3
Total file size: 50 bytes
Total transferred file size: 50 bytes
Literal data: 0 bytes
Matched data: 50 bytes
File list size: 0
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 216
Total bytes received: 95
sent 216 bytes received 95 bytes 622.00 bytes/sec
total size is 50 speedup is 0.16
同步目录下新增的文件到远程主机:
[root@stone ~]# touch d1/f4
[root@stone ~]# rsync -av --compress --stats d1/ root@192.168.92.129:/root
sending incremental file list
./
f4
Number of files: 5 (reg: 4, dir: 1)
Number of created files: 1 (reg: 1)
Number of deleted files: 0
Number of regular files transferred: 1
Total file size: 50 bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 147
Total bytes received: 38
sent 147 bytes received 38 bytes 370.00 bytes/sec
total size is 50 speedup is 0.27
程序
在 Windows 上,安装包的后缀名一般为 msi
或者 exe
,在 CentOS 上,安装包的后缀名一般为 rpm
。
类似于 Windows 上的绿色软件,在 Linux 上也有一些软件,无需安装,解压即可使用。
本节介绍如何在 CentOS 上安装和卸载程序。
RPM
RPM(RedHat Package Manager)是一个运行在 RHEL、CentOS 和 Fedora 上的包管理系统,可以使用 RPM 分发、管理和更新程序。
rpm
使用 rpm
命令安装 RPM 程序包。
常用选项有:
-i
:安装-U
:升级-v
:显示信息-h
:与-v
配合显示进度--nodeps
:安装或升级时不检查依赖-e
:删除-q
:查询-a
:与-q
配合,列出所有安装程序-i
:与-q
配合,列出程序详细信息-l
:与-q
配合,列出程序包含的文件-c
:与-q
配合,列出程序的配置文件-d
:与-q
配合,列出程序的帮助文件-R
:与-q
配合,列出程序的依赖-f
:与-q
配合,列出指定文件属于哪一个程序
安装程序:
[root@stone ~]# rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
Retrieving http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
warning: /var/tmp/rpm-tmp.eD4elk: Header V4 RSA/SHA1 Signature, key ID 7bd9bf62: NOKEY
Preparing... ################################# [100%]
Updating / installing...
1:nginx-release-centos-7-0.el7.ngx ################################# [100%]
程序名称中:
el7
:表示 Enterprise Linux 7,这里就是 CentOS 7noarch
:表示不限制平台。可以是i386
,表示适用于 32 位 x86 平台;可以是x86_64
,表示适用于 64 位 x86 平台
查询是否安装了指定程序:
[root@stone ~]# rpm -qa | grep nginx-release
nginx-release-centos-7-0.el7.ngx.noarch
查询程序信息:
[root@stone ~]# rpm -qi nginx-release-centos-7-0.el7.ngx.noarch
Name : nginx-release-centos
Version : 7
Release : 0.el7.ngx
Architecture: noarch
Install Date: Wed 02 Aug 2023 04:16:41 PM CST
Group : System Environment/Base
Size : 1576
License : BSD
Signature : RSA/SHA1, Tue 15 Jul 2014 10:44:38 PM CST, Key ID abf5bd827bd9bf62
Source RPM : nginx-release-centos-7-0.el7.ngx.src.rpm
Build Date : Tue 15 Jul 2014 10:44:01 PM CST
Build Host : centos7-amd64-ovl
Relocations : (not relocatable)
URL : http://nginx.org
Summary : nginx repo configuration and pgp public keys
Description :
yum config files for nginx repository, and nginx public signing key.
After the package installation you will be able to import the key
to rpm with the "rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-nginx"
command, and turn on option gpgcheck in /etc/yum.repos.d/nginx.repo
查看程序包含的文件:
[root@stone ~]# rpm -ql nginx-release-centos-7-0.el7.ngx.noarch
/etc/pki/rpm-gpg/RPM-GPG-KEY-nginx
/etc/yum.repos.d/nginx.repo
查看程序的配置文件:
[root@stone ~]# rpm -qc nginx-release-centos-7-0.el7.ngx.noarch
/etc/yum.repos.d/nginx.repo
查看文件属于哪个程序:
[root@stone ~]# rpm -qf /etc/yum.repos.d/nginx.repo
nginx-release-centos-7-0.el7.ngx.noarch
删除程序:
[root@stone ~]# rpm -e nginx-release-centos-7-0.el7.ngx.noarch
YUM
使用 RPM 经常会遇到缺少依赖的问题,此时可以使用 YUM(Yellow Dog Updater, Modified)来进行安装。YUM 在更新、安装或删除程序时自动解析依赖关系,自动获取和安装所有可用的依赖包。
那么 YUM 在什么地方去获取依赖包呢?先来看看 YUM 的配置文件 /etc/yum.conf
:
[root@stone ~]# cat /etc/yum.conf
[main]
cachedir=/var/cache/yum/$basearch/$releasever
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release
# This is the default, if you make this bigger yum won't see if the metadata
# is newer on the remote and so you'll "gain" the bandwidth of not having to
# download the new metadata and "pay" for it by yum not having correct
# information.
# It is esp. important, to have correct metadata, for distributions like
# Fedora which don't keep old packages around. If you don't like this checking
# interupting your command line usage, it's much better to have something
# manually check the metadata once an hour (yum-updatesd will do this).
# metadata_expire=90m
# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d
其中 [main]
部分是 YUM 的全局配置,包括:
cachedir
:YUM 的缓存及数据库文件,默认为/var/cache/yum/$basearch/$releasever
,这里有两个变量:$basearch
:系统平台,可以使用arch
命令获取:
[root@stone ~]# arch x86_64
$releasever
:系统版本,从上面的distroverpkg
中获取当前系统为centos-release
,再使用rpm -qi
获取其版本:
[root@stone ~]# rpm -qi centos-release Name : centos-release Version : 7 Release : 8.2003.0.el7.centos Architecture: x86_64 Install Date: Wed 06 Jan 2021 09:48:10 AM CST Group : System Environment/Base Size : 43849 License : GPLv2 Signature : RSA/SHA256, Tue 14 Apr 2020 11:54:48 PM CST, Key ID 24c6a8a7f4a80eb5 Source RPM : centos-release-7-8.2003.0.el7.centos.src.rpm Build Date : Wed 08 Apr 2020 06:01:12 AM CST Build Host : x86-01.bsys.centos.org Relocations : (not relocatable) Packager : CentOS BuildSystem <http://bugs.centos.org> Vendor : CentOS Summary : CentOS Linux release file Description : CentOS Linux release files
可以看到
Version
为 7,故cachedir
为/var/cache/yum/x86_64/7
。直接使用以下命令查看最终的变量值:
[root@stone ~]# python -c 'import yum, json; yb = yum.YumBase(); print json.dumps(yb.conf.yumvar, indent=2)' Loaded plugins: fastestmirror { "uuid": "4380d371-2a81-4aa8-ad89-87fe599cdd54", "contentdir": "centos", "basearch": "x86_64", "infra": "stock", "releasever": "7", "arch": "ia32e" }
logfile
:日志文件
配置文件最下面建议将仓库文件放到 /etc/yum.repos.d
目录中,并以 .repo
作为文件后缀名。
安装完成 CentOS 后,/etc/yum.repos.d
目录下默认会有以下文件:
[root@stone ~]# ll /etc/yum.repos.d/
total 40
-rw-r--r--. 1 root root 1664 Oct 23 2020 CentOS-Base.repo
-rw-r--r--. 1 root root 1309 Oct 23 2020 CentOS-CR.repo
-rw-r--r--. 1 root root 649 Oct 23 2020 CentOS-Debuginfo.repo
-rw-r--r--. 1 root root 314 Oct 23 2020 CentOS-fasttrack.repo
-rw-r--r--. 1 root root 630 Oct 23 2020 CentOS-Media.repo
-rw-r--r--. 1 root root 1331 Oct 23 2020 CentOS-Sources.repo
-rw-r--r--. 1 root root 8515 Oct 23 2020 CentOS-Vault.repo
-rw-r--r--. 1 root root 616 Oct 23 2020 CentOS-x86_64-kernel.repo
在上面每个文件中,配置了一个或者多个仓库,就可以从这些仓库下载安装程序及其依赖。
文件 CentOS-Base.repo
内容如下:
[root@stone ~]# cat /etc/yum.repos.d/CentOS-Base.repo
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
其中:
[base]
:仓库名称mirrorlist
:镜像地址列表,包含多个仓库地址。将变量值代入此 URL 得到 mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock,访问此 URL 可以得到镜像地址列表:
http://mirrors.huaweicloud.com/centos/7.9.2009/os/x86_64/
http://mirrors.ustc.edu.cn/centos/7.9.2009/os/x86_64/
http://mirrors.nju.edu.cn/centos/7.9.2009/os/x86_64/
http://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/os/x86_64/
http://mirrors.jlu.edu.cn/centos/7.9.2009/os/x86_64/
http://mirrors.cqu.edu.cn/CentOS/7.9.2009/os/x86_64/
http://mirrors.bupt.edu.cn/centos/7.9.2009/os/x86_64/
http://mirrors.bfsu.edu.cn/centos/7.9.2009/os/x86_64/
http://mirror.nyist.edu.cn/centos/7.9.2009/os/x86_64/
http://mirrors.qlu.edu.cn/centos/7.9.2009/os/x86_64/
baseurl
:指定一个或者多个仓库的 URL
如果系统自带的仓库不能满足要求,还可以添加额外的仓库。比如前面使用 rpm
命令安装程序 nginx-release-centos-7-0.el7.ngx.noarch
,实际上就是将文件 nginx.repo
拷贝到目录 /etc/yum.repos.d
中,增加一个 NGINX 仓库:
[root@stone ~]# cat /etc/yum.repos.d/nginx.repo
# nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
其中:
[nginx]
:仓库名称baseurl
:仓库地址enabled
:是否启用
配置好仓库后,就可以使用 yum
命令安装程序了。
yum
使用 yum
命令安装程序。
常用选项有:
-y
:对于安装过程中提出的问题,统一回答为 Yes
常用子命令有:
install
:安装程序localinstall
:安装本地 RPM 程序update
:更新程序remove
:删除程序search
:查找程序list
:列出程序info
:列出程序信息repolist
:列出仓库provides
:查找命令对应的安装包history
:列出安装历史clean
:删除缓存数据makecache
:生成缓存数据
查看配置的仓库:
[root@stone ~]# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.huaweicloud.com
* extras: mirrors.huaweicloud.com
* updates: mirrors.huaweicloud.com
repo id repo name status
base/7/x86_64 CentOS-7 - Base 10,072
extras/7/x86_64 CentOS-7 - Extras 518
updates/7/x86_64 CentOS-7 - Updates 5,061
nginx/x86_64 nginx repo 318
repolist: 15,969
查找程序:
[root@stone ~]# yum search nginx
安装程序:
[root@stone ~]# yum install nginx
安装程序,无需确认:
[root@stone ~]# yum install -y bash-completion
查看是否安装了某个程序:
[root@stone ~]# yum list nginx
[root@stone ~]# yum list | grep nginx
查看程序信息:
[root@stone ~]# yum info nginx
Installed Packages
Name : nginx
Arch : x86_64
Epoch : 1
Version : 1.20.1
Release : 10.el7
Size : 1.7 M
Repo : installed
From repo : epel
Summary : A high performance web server and reverse proxy server
URL : https://nginx.org
License : BSD
Description : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and
: IMAP protocols, with a strong focus on high concurrency, performance and low
: memory usage.
查看命令对应的安装包:
[root@ebst2 ~]# yum provides */netstat
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.cqu.edu.cn
* extras: mirrors.nju.edu.cn
* updates: mirrors.cqu.edu.cn
net-tools-2.0-0.25.20131004git.el7.x86_64 : Basic networking tools
Repo : base
Matched from:
Filename : /bin/netstat
net-tools-2.0-0.25.20131004git.el7.x86_64 : Basic networking tools
Repo : @base
Matched from:
Filename : /bin/netstat
yum-config-manager
使用 yum-config-manager
命令修改 YUM 配置文件。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install yum-utils -y
常用选项有:
--add-repo
:增加仓库--enable
:启用仓库--disable
:禁用仓库
增加阿里云的 Docker 仓库:
[root@stone ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror
adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
禁用 NGINX 仓库:
[root@stone ~]# yum-config-manager --disable nginx
[root@stone ~]# cat /etc/yum.repos.d/nginx.repo
# nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=0
启用 NGINX 仓库:
[root@stone ~]# yum-config-manager --enable nginx
[root@stone ~]# cat /etc/yum.repos.d/nginx.repo
# nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
公网 YUM
如果服务器可以访问公网,则可以直接使用公网 YUM 安装程序,常用的公网 YUM 有:
具体使用方法参考官方帮助文档,这里以使用阿里云 CentOS 7 镜像为例:
备份配置文件:
[root@stone ~]# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
下载配置文件:
[root@stone ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
-- 或者
[root@stone ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
生成缓存:
[root@stone ~]# yum makecache
本地 YUM
系统默认的 YUM 仓库都位于公网,如果服务器不能访问公网,可以使用安装系统的 ISO 映像文件配置一个本地 YUM 仓库。
- 挂载 ISO 映像文件到系统
[root@stone ~]# mount /dev/cdrom /media/
[root@stone ~]# ls /media/
CentOS_BuildTag EULA images LiveOS repodata RPM-GPG-KEY-CentOS-Testing-7
EFI GPL isolinux Packages RPM-GPG-KEY-CentOS-7 TRANS.TBL
- 备份原仓库文件
[root@stone ~]# cd /etc/yum.repos.d/
[root@stone yum.repos.d]# mkdir bak
[root@stone yum.repos.d]# mv *.repo bak/
- 添加仓库,在
/etc/yum.repos.d
目录下创建CentOS-Local.repo
:
[root@stone yum.repos.d]# vi CentOS-Local.repo
[local]
name=CentOS Local
baseurl=file:///media/
gpgcheck=0
enabled=1
- 清除并重建缓存
[root@stone yum.repos.d]# yum clean all
Loaded plugins: fastestmirror
Cleaning repos: local
Cleaning up list of fastest mirrors
[root@stone yum.repos.d]# yum makecache
Loaded plugins: fastestmirror
Determining fastest mirrors
local | 3.6 kB 00:00:00
(1/4): local/group_gz | 3.5 kB 00:00:00
(2/4): local/primary_db | 830 kB 00:00:00
(3/4): local/other_db | 203 kB 00:00:00
(4/4): local/filelists_db | 304 kB 00:00:00
Metadata Cache Created
[root@stone yum.repos.d]# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
repo id repo name status
local CentOS Local 446
repolist: 446
局域网 YUM
对于企业来说,为每个服务器配置本地 YUM 太麻烦了,可以使用 NGINX 为可以上公网的服务器配置局域网 YUM,其他不能上公网的服务器访问局域网 YUM 来安装程序。
- 安装 NGINX
[root@stone ~]# yum install nginx
- 拷贝 ISO 映像文件到指定目录
[root@stone ~]# mount /dev/cdrom /media/
[root@stone ~]# mkdir -p /usr/local/nginx/html/centos/7/os/x86_64
[root@stone ~]# cp - /media/* /usr/local/nginx/html/centos/7/os/x86_64
[root@stone ~]# ls /usr/local/nginx/html/centos/7/os/x86_64
CentOS_BuildTag EULA images LiveOS repodata RPM-GPG-KEY-CentOS-Testing-7
EFI GPL isolinux Packages RPM-GPG-KEY-CentOS-7 TRANS.TBL
- 配置 NGINX
[root@stone ~]# cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
[root@stone ~]# vi /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
client_max_body_size 500M;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name 192.168.44.135;
location / {
root /usr/local/nginx/html/centos;
autoindex on;
try_files $uri $uri/ /index.html;
}
}
}
[root@stone ~]# systemctl start nginx
[root@stone ~]# systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
[root@stone ~]# systemctl status nginx
● nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2023-08-03 15:49:07 CST; 21s ago
Docs: http://nginx.org/en/docs/
Main PID: 7804 (nginx)
CGroup: /system.slice/nginx.service
├─7804 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
├─7805 nginx: worker process
└─7806 nginx: worker process
Aug 03 15:49:07 stone systemd[1]: Starting nginx - high performance web server...
Aug 03 15:49:07 stone systemd[1]: Started nginx - high performance web server.
- 其他服务器配置 YUM
[root@stone ~]# cd /etc/yum.repos.d/
[root@stone yum.repos.d]# mkdir bak
[root@stone yum.repos.d]# mv *.repo bak/
[root@stone yum.repos.d]# vi CentOS-Local.repo
[local]
name=CentOS Local
baseurl=http://192.168.44.135/$releasever/os/$basearch/
gpgcheck=0
enabled=1
[root@stone yum.repos.d]# yum clean all
Loaded plugins: fastestmirror
Cleaning repos: local
Cleaning up list of fastest mirrors
Other repos take up 227 M of disk space (use --verbose for details)
[root@stone yum.repos.d]# yum makecache
Loaded plugins: fastestmirror
Determining fastest mirrors
local | 3.6 kB 00:00:00
(1/4): local/7/x86_64/group_gz | 3.5 kB 00:00:00
(2/4): local/7/x86_64/primary_db | 830 kB 00:00:00
(3/4): local/7/x86_64/filelists_db | 304 kB 00:00:00
(4/4): local/7/x86_64/other_db | 203 kB 00:00:00
Metadata Cache Created
[root@stone ~]# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
repo id repo name status
local/7/x86_64 CentOS Local 446
repolist: 446
日志
在系统出现问题后,首先需要做的就是查看对应的日志,找到问题的原因。本节介绍 CentOS 的日志管理。
服务
在 CentOS 7 中,管理日志的服务为 rsyslog
,默认启动。
[root@stone ~]# systemctl status rsyslog
● rsyslog.service - System Logging Service
Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2023-08-04 10:43:24 CST; 4min 13s ago
Docs: man:rsyslogd(8)
http://www.rsyslog.com/doc/
Main PID: 1012 (rsyslogd)
Tasks: 3
Memory: 1.8M
CGroup: /system.slice/rsyslog.service
└─1012 /usr/sbin/rsyslogd -n
Aug 04 10:43:24 stone systemd[1]: Starting System Logging Service...
Aug 04 10:43:24 stone rsyslogd[1012]: [origin software="rsyslogd" swVersion="8.24.0-52.el7" x-pid="1012" x-info="http://www.rsy..."] start
Aug 04 10:43:24 stone systemd[1]: Started System Logging Service.
Hint: Some lines were ellipsized, use -l to show in full.
该服务的配置文件为 /etc/rsyslog.conf
。
[root@stone ~]# cat /etc/rsyslog.conf
# rsyslog configuration file
# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html
# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html
#### MODULES ####
# The imjournal module bellow is now used as a message source instead of imuxsock.
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
#$ModLoad imklog # reads kernel messages (the same are read from journald)
#$ModLoad immark # provides --MARK-- message capability
# Provides UDP syslog reception
#$ModLoad imudp
#$UDPServerRun 514
# Provides TCP syslog reception
#$ModLoad imtcp
#$InputTCPServerRun 514
#### GLOBAL DIRECTIVES ####
# Where to place auxiliary files
$WorkDirectory /var/lib/rsyslog
# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# File syncing capability is disabled by default. This feature is usually not required,
# not useful and an extreme performance hit
#$ActionFileEnableSync on
# Include all config files in /etc/rsyslog.d/
$IncludeConfig /etc/rsyslog.d/*.conf
# Turn off message reception via local log socket;
# local messages are retrieved through imjournal now.
$OmitLocalLogging on
# File to store the position in the journal
$IMJournalStateFile imjournal.state
#### RULES ####
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
# Everybody gets emergency messages
*.emerg :omusrmsg:*
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
# ### begin forwarding rule ###
# The statement between the begin ... end define a SINGLE forwarding
# rule. They belong together, do NOT split them. If you create multiple
# forwarding rules, duplicate the whole block!
# Remote Logging (we use TCP for reliable delivery)
#
# An on-disk queue is created for this action. If the remote host is
# down, messages are spooled to disk and sent when it is up again.
#$ActionQueueFileName fwdRule1 # unique name prefix for spool files
#$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible)
#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
#$ActionQueueType LinkedList # run asynchronously
#$ActionResumeRetryCount -1 # infinite retries if host is down
# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
#*.* @@remote-host:514
# ### end of the forwarding rule ###
其中:
- 第 55 行表示除了
mail
,authpriv
,cron
外,其他类型的info
及以上级别日志写入到/var/log/messages
文件,经常用到。 - 第 58 行表示将
authpriv
类型的所有级别日志写入到/var/log/secure
文件。 - 第 61 行表示将
mail
类型的所有级别日志写入到/var/log/maillog
文件。 - 第 65 行表示将
cron
类型的所有级别日志写入到/var/log/cron
文件。
命令
可以使用以下命令查看相关日志。
last
使用 last
命令查看用户登录日志以及系统启动记录,默认读取 /var/log/wtmp
文件中的数据。
[root@stone ~]# last -5
root pts/1 192.168.44.1 Fri Aug 4 10:47 still logged in
root pts/0 192.168.44.1 Fri Aug 4 10:47 still logged in
reboot system boot 3.10.0-1127.el7. Fri Aug 4 10:43 - 15:27 (04:43)
root pts/2 192.168.44.1 Thu Aug 3 13:51 - down (02:38)
root pts/1 192.168.44.1 Thu Aug 3 10:16 - down (06:13)
wtmp begins Wed Jan 6 09:52:58 2021
dmesg
使用 dmesg
命令查看系统启动信息。
[root@stone ~]# dmesg | head -5
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Initializing cgroup subsys cpuacct
[ 0.000000] Linux version 3.10.0-1127.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ) #1 SMP Tue Mar 31 23:36:51 UTC 2020
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-3.10.0-1127.el7.x86_64 root=/dev/mapper/centos-root ro spectre_v2=retpoline rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
logger
使用 logger
命令将信息写入到日志。
常用选项有:
-t
:为每一行日志指定标签,默认为用户名。
[root@stone ~]# logger "test logger"
[root@stone ~]# tail -1 /var/log/messages
Aug 4 16:13:19 stone root: test logger
日志轮转
随着系统的运行,日志越来越多,为节约磁盘空间,使用日志轮转来自动删除过期的日志。
在 CentOS 中,使用 crond
服务每天调用 logrotate
命令来轮转日志,其脚本为 /etc/cron.daily/logrotate
:
[root@stone ~]# cat /etc/cron.daily/logrotate
#!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
其中:
/var/lib/logrotate/logrotate.status
:被轮转的日志文件将会写入到此文件中/etc/logrotate.conf
:logrotate
命令的配置文件
查看 logrotate
命令配置文件:
[root@stone ~]# cat /etc/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# use date as a suffix of the rotated file
dateext
# uncomment this if you want your log files compressed
#compress
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d
# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
monthly
create 0664 root utmp
minsize 1M
rotate 1
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
# system-specific logs may be also be configured here.
其中:
weekly
:轮转周期,表示每周轮转一次,还可以是hourly
每小时轮转一次,daily
每天轮转一次,monthly
每月轮转一次,yearly
每年轮转一次。rotate 4
:保留 4 个轮转周期。如果轮转周期为weekly
,则会保留之前 4 周的日志。create
:重命名日志后创建一个新的空日志文件。dateext
:为轮转后的日志增加日期后缀。compress
:压缩
以上为通用配置,后面指定需要轮转的日志及单独的配置,会覆盖通用配置:
include /etc/logrotate.d
:各个日志的轮转配置
从通用配置可以看出,默认对日志文件每周轮转一次,保留 4 周,比如对于 /var/log/message
日志,其单独的配置为:
[root@stone ~]# cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
missingok
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
根据通用配置和单独的配置,生成的日志文件如下:
[root@stone ~]# ll /var/log/messages*
-rw------- 1 root root 594820 Aug 4 16:40 /var/log/messages
-rw------- 1 root root 620367 Jul 11 09:23 /var/log/messages-20230711
-rw------- 1 root root 1041844 Jul 18 09:11 /var/log/messages-20230718
-rw------- 1 root root 1229574 Jul 25 10:10 /var/log/messages-20230725
-rw------- 1 root root 1006144 Aug 1 09:01 /var/log/messages-20230801
可以看到,除了当前使用的日志外,还有 4 个以日期为后缀的日志文件。
有的程序会自带日志轮转配置文件,例如 NGINX:
[root@stone ~]# cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
如果程序没有自带日志轮转配置文件,可以根据需要在 /etc/logrotate.d/
目录下创建,例如对于 Oracle 的日志文件,可以配置如下:
[root@fmesdbd1 ~]# cat /etc/logrotate.d/oracle
/u01/app/oracle/diag/rdbms/test/test/trace/alert_test.log
/u01/app/oracle/diag/tnslsnr/stone/listener/trace/listener.log
{
rotate 12
copytruncate
monthly
dateext
nocompress
missingok
notifempty
}
其中:
copytruncate
:与create
不同,拷贝日志文件后,再清空日志文件。notifempty
:如果日志文件为空,则不轮转日志文件。
性能
在硬件确定的情况下,可以通过调整内核参数和资源限制来优化 Linux 性能。
内核参数
Linux 有很多内核参数,启动后目录 /proc/sys
下的文件对应内核参数名称:
[root@stone ~]# ls /proc/sys
abi crypto debug dev fs kernel net sunrpc user vm
[root@stone ~]# cat /proc/sys/net/ipv4/ip_forward
1
类别 | 描述 |
---|---|
abi | Execution domains and personalities |
crypto | Cryptographic interfaces |
debug | Kernel debugging interfaces |
dev | Device specific information |
fs | Global and specific filesystem tunables |
kernel | Global kernel tunables |
net | Network tunables |
sunrpc | Sun Remote Procedure Call (NFS) |
user | User Namespace limits |
vm | Tuning and management of memory, buffer, and cache |
除了直接查看内核参数对应的文件,还可以使用命令 sysctl
查看内核参数的值:
[root@stone ~]# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
使用 -a
选项查看所有内核参数:
[root@stone ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_use_pmtu = 0
常用的内核参数有:
fs.aio-max-nr
:最大允许 AIO 请求数量,默认 65536fs.file-max
:所有进程能够同时打开的文件句柄数量,默认 395458kernel.shmall
:共享内存的总页数,默认 18446744073692774399kernel.shmmax
:单个共享内存段的最大值,默认 18446744073692774399 字节kernel.shmmni
:共享内存段的最大数量,默认 4096kernel.sem
:包含 4 个值,其中semmsl
:第 1 个值,表示一个信号量集合中能够包含的信号量最大数目,默认 250semmns
:第 2 个值,表示允许的信号量最大数目(semmsl * semmni
),默认 32000semopm
:第 3 个值,表示单个semopm()
调用在一个信号量集合上可以执行的操作数量,默认 32semmni
:第 4 个值,表示信号量集合总数,默认 128
net.ipv4.ip_local_port_range
:应用程序可使用的 IPv4 端口范围,默认 32768 60999net.core.rmem_default
:套接字接收缓冲区大小的缺省值,默认 212992 字节net.core.rmem_max
:接字接收缓冲区大小的最大值,默认 212992 字节net.core.wmem_default
:套接字发送缓冲区大小的缺省值,默认 212992 字节net.core.wmem_max
:套接字发送缓冲区大小的最大值,默认 212992 字节vm.min_free_kbytes
:最小保留多少空闲内存空间,默认 67584 KBvm.nr_hugepages
:大页内存值,默认 0vm.swappiness
:控制对 Swap 的使用,越大越倾向于使用 Swap,默认 60
可以直接修改 /proc/sys
下的文件以修改内核参数,但是重启后失效。如果要永久更改,则需要修改 /etc/sysctl.conf
文件或者在目录 /etc/sysctl.d/
下创建配置文件:
[root@stone ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
vm.nr_hugepages=512
[root@stone ~]# cat /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
使用 sysctl -p
加载 /etc/sysctl.conf
中的参数(默认)或者指定配置文件中的参数:
[root@stone ~]# sysctl -p
vm.nr_hugepages = 512
[root@stone ~]# sysctl -p /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
使用 sysctl --system
从上到下加载以下配置文件中的参数:
/run/sysctl.d/*.conf
/etc/sysctl.d/*.conf
/usr/local/lib/sysctl.d/*.conf
/usr/lib/sysctl.d/*.conf
/lib/sysctl.d/*.conf
/etc/sysctl.conf
[root@stone ~]# sysctl --system
* Applying /usr/lib/sysctl.d/00-system.conf ...
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
kernel.yama.ptrace_scope = 0
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.sysrq = 16
kernel.core_uses_pid = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.all.promote_secondaries = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
vm.nr_hugepages = 512
* Applying /etc/sysctl.d/k8s.conf ...
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
* Applying /etc/sysctl.conf ...
vm.nr_hugepages = 512
资源限制
Linux 可以在文件 /etc/security/limits.conf
中配置用户的资源限制,不要影响在系统服务中配置的资源限制。
[root@stone ~]# cat /etc/security/limits.conf
# /etc/security/limits.conf
#
#This file sets the resource limits for the users logged in via PAM.
#It does not affect resource limits of the system services.
#
#Also note that configuration files in /etc/security/limits.d directory,
#which are read in alphabetical order, override the settings in this
#file in case the domain is the same or more specific.
#That means for example that setting a limit for wildcard domain here
#can be overriden with a wildcard setting in a config file in the
#subdirectory, but a user specific setting here can be overriden only
#with a user specific setting in the subdirectory.
#
#Each line describes a limit for a user in the form:
#
#<domain> <type> <item> <value>
#
#Where:
#<domain> can be:
# - a user name
# - a group name, with @group syntax
# - the wildcard *, for default entry
# - the wildcard %, can be also used with %group syntax,
# for maxlogin limit
#
#<type> can have the two values:
# - "soft" for enforcing the soft limits
# - "hard" for enforcing hard limits
#
#<item> can be one of the following:
# - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open file descriptors
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit (KB)
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to values: [-20, 19]
# - rtprio - max realtime priority
#
#<domain> <type> <item> <value>
#
#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student - maxlogins 4
# End of file
其中:
memlock
:可锁定的最大内存,单位 KBnofile
:可打开的最大文件数nproc
:可启动的最大进程数
如果要调整以上资源限制,可以在该文件最后进行修改,修改完成后重新登录即可生效:
[root@stone ~]# tail -2 /etc/security/limits.conf
* hard nofile 65535
* soft nofile 65535
oracle soft memlock 60397977
oracle hard memlock 60397977
其中:
*
:表示针对所有用户配置soft
:表示软限制hard
:表示硬限制
ulimit
使用 ulimit
命令查看各资源限制。
常用选项有:
-a
:列出所有限制-l
:列出内存限制-n
:列出文件限制-u
:列出进程限制
[root@stone ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15632
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
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) 15632
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@stone ~]# ulimit -l
64
[root@stone ~]# ulimit -n
65535
[root@stone ~]# ulimit -u
15632
命令
除了可以使用前面介绍的 ps
,top
命令查看系统运行情况外,还可以使用以下命令查看系统性能情况。
vmstat
使用 vmstat
命令动态显示系统运行情况。
语法为:
vmstat [options] [delay [count]]
其中:
delay
:间隔秒数count
:显示次数
常用选项有:
-s
:内存情况-d
:磁盘情况
每 2 秒显示一次,显示 5 次系统运行情况:
[root@stone ~]# vmstat 2 5
procs -----------memory---------- ---swap-- -----io---- -system- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 1583448 2132 652900 0 0 14 3 114 256 0 0 100 0 0
0 0 0 1583424 2132 652900 0 0 0 0 221 496 0 0 100 0 0
0 0 0 1583424 2132 652900 0 0 0 1 225 502 0 0 100 0 0
0 0 0 1583424 2132 652900 0 0 0 0 213 481 0 1 99 0 0
0 0 0 1583424 2132 652900 0 0 0 0 225 494 0 0 100 0 0
其中:
procs
:表示进程情况,以下两项值越大表示系统越忙r
:运行进程数量b
:不可被唤醒的进程数量
memory
:表示内存情况,单位为 KB,包括:swpd
:使用的 SWAP 大小free
:空闲内存大小buff
:Buffer 大小cache
:Cache 大小
swap
:SWAP 使用情况,包括:si
:每秒从磁盘读取到 SWAP 数据量so
:每秒从 SWAP 写入到磁盘数据量
io
:磁盘 I/O 情况,包括:bi
:每秒从块设备接收到的数据块bo
:每秒发送到块设备的数据块
system
:系统情况,包括:in
:每秒中断数cs
:每秒上下文切换数
cpu
:各类型负载占 CPU 百分比,包括:us
:非内核进程sy
:内核进程id
:闲置状态wa
:等待 I/O 完成st
:虚拟机
查看内存情况:
[root@stone ~]# vmstat -s
1863000 K total memory
234096 K used memory
116996 K active memory
75892 K inactive memory
1495856 K free memory
2108 K buffer memory
130940 K swap cache
3145720 K total swap
0 K used swap
3145720 K free swap
226 non-nice user cpu ticks
0 nice user cpu ticks
477 system cpu ticks
75032 idle cpu ticks
267 IO-wait cpu ticks
0 IRQ cpu ticks
3 softirq cpu ticks
0 stolen cpu ticks
154978 pages paged in
12149 pages paged out
0 pages swapped in
0 pages swapped out
50220 interrupts
199856 CPU context switches
1691498746 boot time
1811 forks
查看磁盘情况:
[root@stone ~]# vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
sda 5306 3 251150 10291 1364 113 20544 386 0 5
sdb 181 0 10513 160 4 0 4096 5 0 0
sdc 154 0 10558 25 0 0 0 0 0 0
sdd 154 0 10558 11 0 0 0 0 0 0
sde 142 0 8046 36 0 0 0 0 0 0
sdf 171 0 9078 24 0 0 0 0 0 0
sdg 157 0 8038 29 0 0 0 0 0 0
sr0 18 0 2056 115 0 0 0 0 0 0
dm-0 3000 0 186685 9611 1467 0 16407 474 0 5
dm-1 88 0 4408 8 0 0 0 0 0 0
dm-2 43 0 2072 29 0 0 0 0 0 0
dm-3 43 0 2072 5 0 0 0 0 0 0
iostat
使用 iostat
命令查看 CPU 和磁盘 I/O 情况。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install sysstat -y
语法:
iostat [options] [ device [...] | ALL ] [ interval [ count ] ]
其中:
interval
:间隔秒数count
:显示次数
常用选项有:
-c
:显示 CPU 使用情况-d
:显示磁盘使用情况-h
:以易读的单位显示-p
:显示指定磁盘分区使用情况-x
:显示扩展信息
每 2 秒显示一次,显示 2 次 CPU 使用情况:
[root@stone ~]# iostat -c 2 2
Linux 3.10.0-1160.el7.x86_64 (stone) 08/08/2023 _x86_64_ (1 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.21 0.00 0.34 0.15 0.00 99.29
avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.00 0.00 0.00 100.00
其中:
%user
:没有修改优先级的用户进程所占 CPU 百分比%nice
:修改了优先级的用户进程所占 CPU 百分比%system
:内核进程所占 CPU 百分比%iowait
:等待 I/O 完成所占 CPU 百分比%steal
:虚拟机所占 CPU 百分比%idle
:闲置状态
查看磁盘使用情况:
[root@stone ~]# iostat -h -x -p sda 2 2
Linux 3.10.0-1160.el7.x86_64 (stone) 08/08/2023 _x86_64_ (1 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.17 0.00 0.29 0.13 0.00 99.41
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda
0.00 0.07 1.93 0.75 70.78 54.15 93.13 0.01 2.88 3.73 0.68 1.27 0.34
sda1
0.00 0.00 0.67 0.01 8.32 0.66 26.78 0.00 0.33 0.31 2.25 0.27 0.02
sda2
0.00 0.07 1.26 0.74 61.97 53.49 115.32 0.01 3.75 5.57 0.67 1.66 0.33
avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.00 0.00 0.00 100.00
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda1
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda2
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
其中:
rrqm/s
:每秒读请求合并次数wrqm/s
:每秒写请求合并次数r/s
:每秒完成的读次数w/s
:每秒完成的写次数rkB/s
:每秒读数据量,单位 KBwkB/s
:每秒写数据量,单位 KBavgrq-sz
:请求的平均扇区数量avgqu-sz
:请求的平均队列长度await
:请求的平均等待时间,单位毫秒r_await
:读请求的平均等待时间,单位毫秒w_await
:写请求的平均等待时间,单位毫秒%util
:I/O 请求所占百分比
perf
使用 perf
命令分析系统性能,查找性能瓶颈,定位热点代码。
如果系统没有这个命令,使用 YUM 进行安装:
[root@stone ~]# yum install -y perf
语法:
perf [--version] [--help] [OPTIONS] COMMAND [ARGS]
其中,常用的 COMMAND
有:
record
:记录命令的运行情况到perf.data
文件。report
:读取perf.data
文件进行分析展示。top
:实时显示系统的性能情况。
记录当前系统运行情况:
[root@stone ~]# perf record
查看运行情况:
[root@stone ~]# perf report
实时显示系统性能情况:
[root@stone ~]# perf top
启动
简单来讲,Linux 7 启动包含以下阶段:
- BIOS:表示 Basic Input/output System,上电后,BIOS 执行开机自检(POST)来识别、检测和初始化系统硬件,加载主引导记录(MBR)。
- MBR:表示 Master Boot Record,是 Linux 引导磁盘的第一个扇区(512 字节)中的信息,用于标识操作系统位于何处和如何定位。在这 512 字节中,引导程序加载器占了 446 字节,接下来的 64 字节为磁盘分区表,最后 2 字节用于校验。MBR 检测可启动的设备,并加载 GRUB2 引导程序到内存中,然后把控制权交给 GRUB2。
- GRUB2:表示 Grand Unified Bootloader,在 CentOS 7 中,GRUB2 是默认的引导程序。GRUB2 配置文件为
/boot/grub2/grub.cfg
。GRUB2 在/boot
查找vmlinuz
内核映像文件,一旦找到,加载到内存中,并提取initramfs
映像文件内容到内存临时文件系统(tmpfs)中。 - KERNEL:搜索
initramfs
映像加载磁盘驱动,挂载根目录并加载其他驱动程序,调用 SYSTEMD。 - SYSTEMD:读取
/etc/systemd/system/default.target
指向的文件,启动各种服务。
文件
在启动的 GRUB2 阶段,需要配置文件 /boot/grub2/grub.cfg
,不要直接修改该配置文件,由命令 grub2-mkconfig
调用配置文件 /etc/default/grub
及目录 /etc/grub.d
下的模板生成。
[root@stone ~]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="spectre_v2=retpoline rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
其中:
GRUB_TIMEOUT
:在开机选择菜单项的超时时间,超过该时间将使用默认的菜单项来引导对应的操作系统。默认 5 秒。等待过程中,按下任意按键都可以中断等待。GRUB_DEFAULT
:默认启动项,saved
表示使用grub2-set-default
命令以序号(从 0 开始)指定的默认启动项,可以选择的启动项有:
[root@stone ~]# awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg
CentOS Linux (3.10.0-1127.el7.x86_64) 7 (Core)
CentOS Linux (0-rescue-9de1d34c53954b70bea8260cbd106b49) 7 (Core)
GRUB_CMDLINE_LINUX
:添加到菜单中的内核启动参数。
命令
本节介绍与关机,重启相关的命令。
shutdown
使用 shutdown
命令关闭和重启主机。
语法:
shutdown [OPTIONS...] [TIME] [WALL...]
其中:
TIME
:为时间字符串,可以是now
表示立即执行,可以是hh:mm
表示在指定时间执行,还可以是+m
表示m
分钟后执行,默认为+1
常用选项有:
-P
:关闭系统并断电,默认-h
:关闭系统并断电-r
:重启-k
:不关机,仅发送消息给登录用户-c
:取消关机
立即关机:
[root@stone ~]# shutdown -h now
立即重启:
[root@stone ~]# shutdown -r now
poweroff
使用 poweroff
命令关闭主机。
立即关机:
[root@stone ~]# poweroff
reboot
使用 reboot
命令重启主机。
立即重启:
[root@stone ~]# reboot
init
使用 init
命令关闭和重启主机。
立即关机,也就是切换到运行级别 0:
[root@stone ~]# init 0
立即重启,也就是切换到运行级别 6:
[root@stone ~]# init 6
安全
从 CentOS 7 开始,默认使用 firewalld 来配置防火墙。
架构
firewalld 分为两层:
- D-Bus:用于防火墙配置工具的接口。
- Core:处理配置。
区域
相较于传统的防火墙管理配置工具,firewalld 支持动态更新技术并加入了区域(zone)的概念。简单来说,区域就是预先准备的防火墙策略集合(策略模板),用户可以根据生产场景选择合适的策略集合,从而实现防火墙策略之间的快速切换。
根据从不受信任到受信任的区域的默认信任级别进行排序,预定于的区域有:
drop
:任何传入的网络数据包都将被丢弃,没有回复。block
:任何传入的网络连接都将被拒绝,IPv4 显示icmp-host-prohibited
,IPv6 显示icmp6-adm-prohibited
。public
:用于公共区域,仅接受设定的传入连接。默认区域。external
:用于启用了 IPv4 伪装的外部网络,仅接受设定的传入连接。dmz
:适用于非军事区内可公开访问且对内部网络的访问权限有限的计算机,仅接受设定的传入连接。work
:用于工作区域,仅接受设定的传入连接。home
:用于家庭区域,仅接受设定的传入连接。internal
:用于内部网络,仅接受设定的传入连接。trusted
:接受所有网络连接。
服务
在 CentOS 7 中,防火墙服务为 firewalld
,默认启动。
[root@stone ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2023-08-09 20:57:08 CST; 4min 34s ago
Docs: man:firewalld(1)
Main PID: 791 (firewalld)
CGroup: /system.slice/firewalld.service
└─791 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
Aug 09 20:57:07 stone systemd[1]: Starting firewalld - dynamic firewall daemon...
Aug 09 20:57:08 stone systemd[1]: Started firewalld - dynamic firewall daemon.
Aug 09 20:57:08 stone firewalld[791]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option.... it now.
Hint: Some lines were ellipsized, use -l to show in full.
关闭,启动和重启服务器服务:
[root@stone ~]# systemctl stop firewalld
[root@stone ~]# systemctl start firewalld
[root@stone ~]# systemctl restart firewalld
开机禁用和开机启用服务器服务:
[root@stone ~]# systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@stone ~]# systemctl enable firewalld
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.
命令
firewall-cmd
使用 firewall-cmd
命令配置防火墙。
常用选项有:
--state
:防火墙状态--reload
:重载防火墙规则,动态添加规则--complete-reload
:重载防火墙规则,相当于重启防火墙服务--runtime-to-permanent
:将临时设定创建为永久设定--check-config
:检查永久设定配置--permanent
:永久设定,重启防火墙服务后仍有效--get-default-zon
:默认区域--set-default-zone=<zone>
:设置默认区域--get-active-zone
:当前活动区域--get-zones
:预定义区域--get-services
:预定于服务--zone=<zone>
:指定区域,否则使用默认区域--list-all
:列出区域中的配置--list-ports
:列出区域中的端口--add-port=<portid>[-<portid>]/<protocol>
:为区域添加端口--remove-port=<portid>[-<portid>]/<protocol>
:从区域删除端口--query-port=<portid>[-<portid>]/<protocol>
:是否开放了指定端口--list-services
:列出区域中的服务--add-service=<service>
:为区域添加服务--remove-service=<service>
:从区域删除服务--query-service=<service>
:是否开放了指定服务--list-protocols
:列出协议--add-protocol=<protocol>
:为区域增加协议--remove-protocol=<protocol>
:从区域删除协议--query-protocol=<protocol>
:是否开放了指定协议--panic-on
:启用应急模式,拒绝所有流量,远程连接会立即断开,只有本地能登陆--panic-off
:关闭应急模式--query-panic
:是否启用了应急模式
查看防火墙状态:
[root@stone ~]# firewall-cmd --state
running
查看预定义区域:
[root@stone ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
查看当前默认区域:
[root@stone ~]# firewall-cmd --get-default-zone
public
查看当前活动区域:
[root@stone ~]# firewall-cmd --get-active-zones
public
interfaces: ens33
查看指定区域的配置:
[root@stone ~]# firewall-cmd --zone=public --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
开放指定区域指定端口,重载防火墙规则再查看:
[root@zabbix ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[root@zabbix ~]# firewall-cmd --reload
success
[root@zabbix ~]# firewall-cmd --zone=public --list-ports
80/tcp
[root@zabbix ~]# firewall-cmd --zone=public --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client ssh
ports: 80/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
查看预定义的服务:
[root@zabbix ~]# firewall-cmd --get-services
RH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius redis rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
查看指定区域开放的服务:
[root@zabbix ~]# firewall-cmd --zone=public --list-services
dhcpv6-client ssh
开放 mysql
服务:
[root@zabbix ~]# firewall-cmd --zone=public --add-service=mysql --permanent
success
[root@zabbix ~]# firewall-cmd --reload
success
[root@zabbix ~]# firewall-cmd --zone=public --list-services
dhcpv6-client mysql ssh
[root@zabbix ~]# firewall-cmd --zone=public --query-service mysql
yes
[root@zabbix ~]# firewall-cmd --zone=public --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client mysql ssh
ports: 80/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules: