Linux配置和管理
文件管理
在Linux/UNIX中,所有的对象都被视为文件,包括普通文件、目录、设备、套接字。
目录路径
pwd # Print Working Directory
dirname filename # parent directory
basename filename #
pwd
列出正在工作的目录,用于显示你当前所处的目录名。pwd
命令总是返回你当前所处的目录的完全路径名。dirname
返回查询路径的父目录(从文件路径中截取)。basename
仅返回文件的名称。
readlink
和realpath
解析文件的绝对路径,跟踪解析所有符号链接。
readlink -e \ # 解析过程中的所有目标必须存在 => realpath -e filename
-f \ # 除最终目标外所有目标必须存在 => realpath filename
-m \ # 允许目标不存在 => realpath -m filename
FILENAME
切换目录
cd [dir_name] # 切换工作目录(Change Directory)
chroot [OPTION] NEWROOT [COMMAND [ARG]...] # 切换命令运行的根目录
不带任何参数时,将把你送回自己的用户主目录中(等效于
cd ~
)。..
表示父目录。登录完成后,工作目录为用户主目录。
创建目录
在每一个新的子目录中,均包含两个标准的项目:.
代表当前目录和..
代表父目录。
mkdir -m,--mode=MODE -p dir_name
install [OPTIONS] -d dir1 dir2 ... # 创建目录并设置权限
-m
:可用来创建一个带有特定权限的子目录(chmod
声明方式)。-p
:父目录不存在的情况下首先创建父目录,忽略已存在目录(默认报错)。
删除目录
rmdir -p dir_name ... # -p 一次删除多个目录
dir_name
不能为当前工作目录(即要在父目录中删除子目录)。应该拥有被删除目录的写该目录必须为空目录(即只包含.
和..
,否则使用rm -rf dir_name
)。
显示目录中的项目
列表显示
ls [options] [dir_name]
文件过滤选项
-a
:显示所有文件(包括以.
开头的文件(夹)),-A
仅忽略.
和..
;
-R
:递归显示所有子目录的内容;
-d
:只显示目录条目的信息;
文件信息选项
-l
:列表显示目录中文件的详细信息,与其他排序方式组合使用时则显示相应的排序字段;-g
与-l
相似但不显示文件所有者,-o
不显示用户组;
文件类型信息:
-
表示普通文件(f
);d
目录文件;b
块设备文件例如磁盘;c
字符设备文件,p
命名管道(FIFO) ;l
符号链接;s
套接字(socket);
--author
:显示文件创建者;
-n
:显示数字形式的用户和用户组ID;
-i
:inode
序号将列在第一列;
--time-STYLE
:时间显示格式,包括:full-iso
(2020-03-07 15:07:15.542112573 +0800
)、long-iso
(2020-03-07 17:34
)、iso
(03-07 15:07
)、locale
(Mar 7 15:07
)或+FORMAT
;
--full-time
:显示完整时间,等价于-l --time-style=full-iso
;
-h
:显示更加友好的文件长度信息(1K 234M 2G
,等价--human-readable
);
-s
:显示文件占用的磁盘容量;
--block-size=SIZE
:K,M,G,T,P,E,Z,Y
(powers of 1024)或 KB,MB,...
(powers of 1000)
排序选项
--sort=WORD
:WORD=none(-U),size(-S),time(-t),version(-v),extension(-X)
,未声明排序选项时,默认按文件名排序。-c
:按ctime
(指文件的inode
信息被改变的时间)排序;-u
:按访问时间排序;-t
:按修改时间排序,优先级低于-c
和-u
;
-r
:反向排序;
查看目录树
tree -L <n> path # not built-in
-L <n>
:搜索深度;-l
:跟踪符号链接;
文件信息
获取文件的信息:
stat <path/to/file> -c,--format,--printf=FORMAT \
-f,--file-system # 显示文件所在文件系统信息而非文件信息
格式参数FORMAT
可包含多个格式声明以及普通字符,--printf
还可使用"\"
转义字符;
格式 | 内容 | 格式 | 内容 | 格式 | 内容 | 格式 | 内容 | 格式 | 内容 |
---|---|---|---|---|---|---|---|---|---|
%n | 文件名 | %F | 文件类型 | %g | group id | %y | 修改时间 | %a | 八进制访问权限 |
%N | "文件名" | %s | file bytes | %G | group name | %Y | 修改时间戳 | %A | 字母访问权限 |
%h | 硬链接数 | %m | 挂载点 | %u | owner id | %w | 创建时间 | %x | 访问时间 |
%i | inode数 | %C | SELinux | %U | owner name | %W | 创建时间戳 | %X | 访问时间戳 |
除stat
外,还可以使用date
获取文件修改时间:
date -r <filename> [+"%Y%m%d"]
获取文件类型:
file <path/to/file> \
-i,--mime \ # => --mime-type + --mime encoding
-z,--uncompress \ # 尝试解压压缩文件并查看其中内容
修改文件属性
touch
可以用于修改文件访问时间。
touch filename
touch -d "2 hours ago" filename
普通文件
移动
如果源文件/目录与目标文件/目录同名,则用源文件/目录替换同名目标文件/目录的内容;否则,将源文件/目录移动到目标目录中;此时,目标目录必须存在,不会首先创建目录。
mv [-f] file_path /path/newname
如果源与目标所在路径相同,
mv
等效于重命名。
批量重命名
将文件名中已知的部分内容替换为新的内容,其余部分(使用通配符表示)不变。
rename 's/pattern/replace/' FILES # sed style
rename pattern replace FILES
pattern
为Perl正则表达式,文件名FILES
支持通配符(?*.txt
)。
使用需注意,原始的
rename
不会检查已有文件而直接覆盖。
复制
cp [-raf] file_path /path/filecopy # -a 保留原属性
cp
的文件创建行为与mv
相同。
安装
install
支持设置目标文件的权限和属性(==不支持文件夹(递归)复制==):
-
-m,--mode=MODE
:设置访问权限; -
-g,--group=GROUP
,-o,--owner=OWNER
:设置所属关系(chgrp,chown
),代替当前进程的默认值; -
-p, --preserve-timestamps
:保留文件的访问/修改时间;
install [OPTION] -D [-T] SOURCE DEST # single-file to file
-D
:(递归)创建目标文件的父目录(mkdir -p
),未指定该选项则不会自动创建目录;
install [OPTION] SOURCE... DIRECTORY # single to dir
install [OPTION] -t DIRECTORY SOURCE...# multiple to dir (--target-directory)
-b,--suffix=BACKUP
:备份选项以及备份目标文件夹;
删除文件
rm [-rf] file # can use wildcard
使用
-rf
递归删除非空文件夹。
文件链接
硬链接(hard link):是对原文件的引用(引用同一个inode
,在inode
中计数),与原文件等价(即拥有相同访问权限)。删除硬链接将减小inode
计数,到inode
计数为0时删除文件。
符号链接(symbolic/soft link):保存到目标文件(夹)的路径(或相对路径),访问符号链接将跳转到目标文件(夹)。符号链接是一个独立的文件(具有相应的inode
节点),因此具有独立的文件权限。删除原文件后,符号链接失效。
创建链接
ln -s /file/path /symbol/path # symbolic link
ln /file/path /symbol/path # hard link file
ln -d /dir/path /symbol/path # hard link 目录(不一定支持)
# -f,--force 移除已有文件链接
符号链接的目标可以是任意内容(创建的时候不做检查合法性),符号链接支持跨文件系统。硬链接的目标必须存在且仅支持在同一设备的同一文件系统。
访问链接
==文件链接解引用时,相对路径的父目录为文件链接所在目录==,解析符号链接目标时是递归式解析。
工作目录路径:如果切换工作目录到符号链接指向的目录,则工作目录路径为符号链接的路径而非目标目录的真实路径(比较pwd
和realpath
的输出结果),向上跳转(..
)会返回符号链接所在目录。
在Linux中创建的符号链接在Windows中仍然能访问(WSL),但Windows不做递归解析,仅以当前工作目录路径为参考解析符号链接,因此使用相对路径的多级符号链接解析会出错。
临时文件
在指定目录下(默认为/tmp
)创建临时文件并输出文件路径。
tempfile --directory PATH # [Debian]
mktemp -p PATH # [Fedora-coreutils]
--directory # 创建目录而非文件
查找文件
which <command>
command -V <command>
从系统环境变量中查找文件并返回绝对路径。
查找目录中的文件
find [-HLP][-D debugopts][-Olevel][start_dir...][expression]
start_dir
表示查找路径,可以使用绝对路径,也可以使用相对路径,可以同时指定多个目录;如果没有指定,则默认为当前目录。==默认输出信息为查找到的文件夹和文件信息,并包含从查找目录开始的完整路径信息。==
选项(Option)
选项控制find
访问文件系统的行为。
-H
,-L
和-P
(默认)控制处理符号链接的行为。
-P
表示不解析任何符号链接;-H
表示除了命令行提供的文件名外,不解析其他符号链接。如果符号链接不能被解析,则返回符号连接本身的信息;-L
表示在可能的情况下解析符号链接,反之返回符号链接自身的信息。(-follow
deprecated)
-D debugopts
:输出诊断信息。
-Olevel
:查询优化。默认首先执行基于文件名的表达式(-name
,-regex
等);其次执行-type
或-xtype
的表达式(通过readdir()
读取文件类型)。
读取上述选项之后,检查后续参数是否为文件/路径,直到以-
、(
、!
开始的参数(也可以使用--
声明选项参数的结束)。剩余参数为控制搜索行为的表达式。
表达式(Expression)
表达式用于控制如何匹配文件以及对匹配文件的操作。表达式可以包含以下内容:
Tests
:测试文件属性,返回true|false
;Actions
:对匹配结果执行操作,根据操作结果返回true|false
;如果表达式没有包含操作,则默认为-print
;Global options
:全局选项,总是返回true
;Positional options
:仅影响其后的测试或操作,总是返回true
;Operator
:将表达式中多个内容连接起来:-o
(逻辑OR
)、-a
(逻辑AND
);表达式内容之间默认使用-a
连接;可以使用()
声明优先级。
全局选项
-d,-depth
:先处理文件夹中的内容,再处理文件夹本身;-maxdepth,-mindepth LEVEL
:指定搜索的层级,0
表示起始点本身;-mount, -xdev
:不搜索挂载的其他文件系统目录;-help,--help,--version
:帮助、版本信息。
位置选项
-
-daystart
:计算时间时从今天开始,而非24小时前算起。影响其后的测试条件-amin
,-cmin
,-mmin
,-atime
,-ctime
和-mtime
。 -
-regextype TYPE
:默认为emacs
,包括:awk,egrep,grep,sed
等。-regextype egrep
在CentOS 7 上不支持{}
。
测试条件
表达式 | 说明 |
---|---|
-name PATTERN | 查找==文件名==匹配PATTERN 的文件,可以使用通配符*,?,[] 。 |
-path PATTERN | ==从搜索路径开始的完整文件名(非绝对路径)==与PATTERN 进行匹配( -wholename )。 |
-regex PATTERN | 使用正则表达式匹配文件。文件名以./ 开头的==完整相对路径==,注意在正则表达式前添加 .* 以匹配前缀; |
-atime [+-]N -ctime [+-]N -mtime [+-]N | 判断最近访问(-a ),状态变化(-c ),修改(-m )时间:如果参数为 N ,表示时间在N 天之内(0表示0~24小时,1表示24~48小时,…) |
-amin [+-]N | 时间单位为min (类似地-cmin ,-mmin ) |
-anewer FILE | 测试最近访问时间是否比FILE 更近(-cnewer,-newer )。 |
-used [+-]N | 在文件状态改变N 天(+N,-N )之内文件被访问过。 |
-empty | 测试文件或文件夹是否为空。 |
-size n[u] | 文件大小:单位u=cwbkMG: |
-fstype TYPE | 测试文件所在的文件系统的类型是否为TYPE 。 |
-uid [+-]N | 文件的用户ID(组ID-gid )是否为N (或+N,-N )。 |
-user NAME | 文件的用户名(组名-group )是否为NAME (允许使用ID)。 |
-nouser | 文件的用户ID(组ID-nogroup )没有对应的用户(组)。 |
-lname PATTERN | 符号链接所指向的文件的文件名是否与PATTERN 匹配。 |
-perm pmode | 文件的权限是否与pmode 匹配,pmode 可以是符号或数字模式,例如:-perm 664 。直接指定单项权限 -readable 、-writable 、-executable 。 |
-type <c> | 文件类型: bcdpfls |
-xtype c | 除符号链接以外,与-type 作用一致; |
-inum [+-]N | rarely useful. |
-samefile NAME | 文件与NAME 为同一个文件。 |
-links [+-]N | File has n hard links. |
匹配文件名的测试命令前添加
i
(例如-iname
)为忽略大小写版本。 通配符需要使用引号包围以防被shell展开。 参数如果为+N
,则表示大于N
,如果为-N
则表示小于N
。
运算符
运算符 | 表达式 |
---|---|
() | (EXPR) |
! -not | !EXPR –not EXPR |
-a -and | EXPR1 –a EXPR2 EXPR1 –and EXPR2 |
-o -or | EXPR1 –o EXPR2 EXPR1 –or EXPR2 |
, | EXPR1, EXPR2 |
动作
命令 | 说明 |
---|---|
-print, -print0 | print0 会在文件名结尾追加“null ”。 |
-fprint FILE -fprint0 FILE | 打印完整文件名到FILE 。如果文件不存在则创建文件; 如果存在,则文件内容被删除; 即使没有输出内容,该文件仍然会被创建。 |
-ls -fls FILE | 以ls -dils 格式打印到标准输出。-fls 输出到文件。 |
-printf FORMAT -fprintf FILE FORMAT | 位宽和精度说明类似于C语言的printf (man find )。 |
-execdir command -exec command | -execdir 将其后直到; 的所有内容视为command ,同时将其中的“ {} ”替换为查找结果的文件名。command 中的特殊字符需要使用“\ ”或“' ”以防被shell展开。 |
-execdir command {}+ -exec command {}+ | 命令末尾的“{} ”展开为匹配文件名称的列表; |
-okdir command -ok command | 询问用户是否执行命令 |
-delete | 删除成功返回真;如果失败,生成错误信息; |
查找文件示例
高亮find
查找结果:
find ./ -name '*.tar.gz' | grep --color '.tar.gz'
打印查找到文件的详细信息。
find ./ -name '*.tar.gz' -exec ls -lh {} ';'
删除文件:
find . -maxdepth 1 -newer archive.tar.gz -execdir rm -rf {} ';'
在过滤文件中查找内容:
find ./ –name '*.cpp' –exec grep -Hn 'main' {} ';'
find ./ -name "*.log" | xargs grep –Hn 'ERROR'
grep
与find
同时使用时,默认不会输出文件名(添加-H
选项),也不会高亮文本(使用--color
选项)。
查找文件内容
使用grep
查找具有给定内容和文件名的文件:
grep -rl 'main' --include='*.cpp' ./ # 输出匹配文件的文件名
grep -rn 'main' --include='*.cpp' ./ # 输出匹配行的行号和内容
硬件管理
查看硬件信息
sudo dmidecode -t,--type type_code|type_keyword
sudo dmidecode [options] | grep -A16 'System Information$' # 系统和主板信息
硬件类型(type_keyword
)包括:bios
, system
, baseboard
, chassis
, processor
, memory
, cache
, connector
, slot
。每种类型可能包括多个子类型(type_code
)。
sudo lshw \ # list hardware [yum install lshw]
-class <hw_class> \ # class can be found using lshw -short
-{html|xml|json} \ # 输出格式
-short \ # device tree: 优先级高于输出格式
-businfo # showing bus information
硬件类型可通过lshw -short
的输出获取,包括:system
,bus
,memory
,processor
,storage
,input
,display
,disk
,volume
,network
,power
等。
其他工具:
hwinfo
(默认未安装到系统);hardinfo
(图形界面)。
CPU
lscpu # CPU信息概述
nproc # number of process unit
sudo lshw -C processor
cat /proc/cpuinfo # CPU details
sudo dmidecode --type processor # details
cpuid
获取详细信息(未安装)。
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
# 8 Intel(R) Xeon(R) CPU E5410 @ 2.33GHz
## (CPU with 8 logical core)
cat /proc/cpuinfo | grep 'physical id' | uniq -c
# 4 physical id : 0
# 4 physical id : 1
### (2 physical CPU with 4-core)
内存
free -h -w # summary
cat /proc/meminfo # details
vmstat -s
sudo dmidecode -t memory # Memory Device
all tmpfs pages will be shown as “
Shmem
” in/proc/meminfo
and “Shared
” infree(1)
.
磁盘信息
列出存储设备信息:
sudo fdisk -l [device_name] # 查看磁盘设备 => sudo parted /dev/sda print
lsblk # 列出块设备
sudo blkid /dev/sda
# /dev/sda: UUID="3255683f-53a2-4fdf-91cf-b4c1041e2a62" TYPE="ext4"
查看序列号:
udevadm info --query=all --name=/dev/sda | grep ID_SERIAL
hdparm -I /dev/sda # install hdparm
lshw -class disk # install lshw
smartctl -i /dev/sda # install smartmontools
位于磁盘阵列中的磁盘序列号不可见(系统读取的是RAID分配的ID)。
文件系统信息
列出系统支持的文件系统:
cat /proc/filesystems
exfat
格式支持需要安装exfat-fuse
和exfat-utils
包;NTFS格式需要安装ntfs-3g
包(CentOS)。
列出挂载的(文件或目录所在)文件系统信息。
df [-ahHkT] [目录或文件名]
# Filesystem Size Used Avail Use% Mounted on
# /dev/sdd 251G 1.6G 237G 1% /
# tmpfs 13G 252M 13G 2% /mnt/wsl
-hH
:以合适的单位显示数据(1024进制,-H
为1000进制),提高可读性;-i,--inodes
:显示inode
信息而非磁盘容量信息;-T,--print-type
:==打印文件系统类型==,例如ext4
、tmpfs
等;-t,--type=TYPE
:仅显示指定类型文件系统;-x,--exclude-type=TYPE
排除指定类型;
列出文件或目录的磁盘占用量(disk usage):
du [-ahskm] 文件或目录名称
-c, --total
;
-h, --human-readable
;
-s, --summarize
;
-d,--max-depth=N
:显示最大路径深度;
磁盘管理
磁盘分区与格式化
注意:以下操作可能导致数据丢失,应事先做好数据备份!!!
使用fdisk
或parted
操作文件分区表(fdisk -l
查看磁盘信息):
sudo fdisk device_name # 操作分区表
# fdisk命令
# [F] 列出未分区的空闲空间 n 新增分区
# l 列出已知分区类型 t 更改分区类型
# p 打印分区表 d 删除分区
# [i] 打印选择的分区信息 v 验证分区表
# m 打印命令列表 g 创建GPT分区表
# o 创建DOS(MBR)分区表
# q 放弃更改并退出 w 保存分区更改
未添加
device_name
时,列出系统内所有存储设备(/dev
)的分区(partition)信息。GParted -- Live CD/USB/PXE/HD:With GParted you can resize, copy, and move partitions without data loss.
gparted
是一款图形界面的分区工具。
更改正在使用的分区:首先删除分区(记录下分区表的起止位置),然后重新创建分区,并指定新的起止位置(注意不要和已有分区重叠)和分区类型,保存并退出(使用工具cloud-utils.growpart
)。分区表更改不会立即生效,因此可以修改正在使用的分区,重启机器或使用partprobe [/dev/sda]
或kpartx [/dev/sda]
命令重新载入新的分区表。如果是普通卷,则需要使用resize2fs
更新文件系统容量,如果是LVM物理卷,则使用pvresize
更新(resize2fs
无法操作LVM物理卷)。
磁盘格式化
新建分区后,需要对分区进行格式化设置文件系统才能进行挂载使用。整个磁盘也可以不进行分区直接格式化。
mkfs -t <fstype> /dev/sda
mkfs.<fstype> options /dev/sda # 格式化分区/dev/sda1
fstype
文件系统类型,例如 ext4
, xfs
, btrfs
, ZFS
等(系统有支持才会生效)。在选择文件系统类型时,如无特殊要求,选择系统中已有分区类型(默认类型),确保兼容和稳定性。
mke2fs
:创建ext2
/ext3
/ext4
文件系统,对应命令:mkfs.ext2|3|4
。ext
文件系统的i-node
节点总数在文件系统创建后不能改变,调整文件系统容量将按比例调整inode数量(bytes-per-inode
)。
Linux File System Types Explained, Which One Should You Use (linuxiac.com)
数据恢复
TestDisk Step By Step - CGSecurity
How to recover partitions and data using Linux - Tutorial (dedoimedo.com)
How to recover lost partition using Linux (simplified.guide)
TestDisk is powerful free data recovery software! It was primarily designed to help recover lost partitions and/or make non-booting disks bootable again when these symptoms are caused by faulty software: certain types of viruses or human error (such as accidentally deleting a Partition Table).
==Even though the old partition table was destroyed, it was just a pointer to the start and end addresses of the actual data, so to speak.==
The new and definite CloneZilla tutorial (dedoimedo.com)
磁盘检验
fsck [-t <fstype>] [-ACay] /dev/sda
用来检查和维护不一致的文件系统。若系统掉电或磁盘发生问题,可利用
fsck
命令对文件系统进行检查。
磁盘挂载与卸除
mount -t <fstype> -L <label> -o <opts> -n /dev/dev_name /mnt/mnt_name
mount --move /mnt/userdirs /home # move mount point of a filesystem
umount [-fn] [/dev/dev_name | /mnt/mnt_name]
findmnt --types <fstype> # 查看已挂载的文件系统
如果挂载的目标路径下有数据,则数据会被隐藏;卸载磁盘后可恢复访问原有数据1。
挂载NTFS文件系统:
yum install fuse ntfs-3g # centos
mount -t ntfs-3g /dev/sdb1 /mnt/win
如果卸除设备时出现设备忙的错误,可查看正在使用该设备的进程有哪些并尝试关闭进程。
挂载CD
mount -t auto [-r] /dev/cdrom /mnt/cdrom # 挂载CD
挂载可移动介质
挂载磁盘的目标文件夹必须存在,挂载的磁盘应该已经使用支持的文件系统格式化。可移动磁盘设备标识类似于内置磁盘(使用fdisk -l
或parted -l
查看)。
自动挂载
-
将挂载命令写入开机启动脚本;
-
配置
systemd.mount
单元文件;[Mount] What=/dev/sda Where=/data Type=ext4 Options=
-
使用
/etc/fstab
配置,systemd
会将其中的内容转换为单元文件;# DevicePath MountPoint FS Type Mount Options Dump CheckOrder /dev/sdba /data ext4 - 0 1 LABEL=t-home2 /home ext4 defaults,auto_da_alloc 0 2 SERVER:PATH
逻辑卷管理LVM
Logical Volume Management, gives users the power to pool and abstract the physical layout of component storage devices, to gather existing storage devices into groups and allocate logical units from the combined space as needed.
LVM存储信息
显示系统中的LVM兼容卷,包括可转换为LVM物理卷(Physical Volumns)的存储设备:
sudo lvmdiskscan \
-l # 仅显示LVM物理卷, ==> pvscan, pvs, pvdisplay
显示系统中的物理卷组(Virtual Group)信息:
sudo vgscan # => vgs, vgdisplay
显示系统中的逻辑卷(Logical Volumn):(逻辑卷设备路径、VG Name
、PV
)
sudo lvscan # lvs, lvdisplay [-m]
管理LVM存储
从原始磁盘创建LVM物理卷,注意将磁盘上原有数据备份,加入LVM管理后将覆盖原有数据。
A header is written to storage devices to mark them as free to use as LVM components.
sudo pvcreate /dev/sda /dev/sdb ...
pvresize /dev/sda1
pvresize --setphysicalvolumesize 40G /dev/sda1 # shrink
如果物理磁盘分区通过
fdisk
进行了扩展,可以通过pvresize
更新LVM物理卷的容量。也可以将空余磁盘空间创建为一个新的物理分区,设置为LVM PV并加入LVM虚拟卷组。
将物理卷创建为卷组,通常只需要一个卷组并在此之上创建虚拟卷。
sudo vgcreate volume_group_name /dev/sda /dev/sdb ...
向卷组中增加物理卷:
sudo vgextend volume_group_name /dev/sdb
创建虚拟卷,创建后需要对虚拟卷进行格式化。
sudo lvcreate -L 10G -n VolumnName LVMVolGroup # 绝对容量
sudo lvcreate -l 100%FREE -n VolumnName2 LVMVolGroup # 相对容量
虚拟卷的底层物理磁盘分配方案支持线性(
linear
,默认)、striped
(RAID 0)、raid1
等。
虚拟卷容量调整,使用-L
选项增加/减少绝对容量,或用-l
选项增加相对容量。
sudo lvresize -L +5G --resizefs LVMVolGroup/vol_name
sudo lvresize -l +100%FREE --resizefs LVMVolGroup/vol_name
XFS filesystem shrinking is unsupported.
resize2fs
is for ext filesystems.
RAID
Hardware RAID
在BIOS中配置磁盘的RAID选项,参考产品用户手册。
Software RAID
- How To Use LVM To Manage Storage Devices on Ubuntu 18.04.
- How To Create RAID Arrays with mdadm on Ubuntu 18.04 | DigitalOcean.
显示设备
查看显示设备:
lspci | grep -i vga # <== install pciutils
sudo lshow [-short] -c CLASS # list hardware, CLASS for class/description
sudo lspci -v -s 03:00.0
安装Nvidia显卡驱动
rl=$(uname -r)
yum install gcc gcc-c++ make kernel-devel-$rl kernel-headers-$rl
apt install gcc make linux-headers-$rl [libglvnd]
注意内核开发包的版本需要于系统内核版本完全一致,否则无法成功安装驱动程序。
检查nouveau
模块是否加载,已加载则先禁用
lsmod | grep nouveau
# edit: /usr/lib/modprobe.d/blacklist-nouveau.conf # [Ubuntu]/etc/modprobe.d/*
blacklist nouveau
options nouveau modeset=0
dracut -force # 重启系统,使内核模块配置生效 [Ubuntu]update-initramfs -u
安装驱动程序:
./NVIDIA-Linux-x86_64-390.46.run --no-opengl-files --ui=none --no-questions --accept-license
# edit: /etc/rc.d/rc.local
nvidia-smi -pm 1 # GPU驱动模式设置为常驻内存
nvidia-smi # nvidia proprietary driver => watch -n 1 nvidia-smi
Ubuntu桌面版显卡驱动
ubuntu-drivers devices # 列出可用驱动
sudo ubuntu-drivers autoinstall # 安装推荐驱动
sudo apt install nvidia-driver-440 # 安装指定名称驱动
安装完成后重启。
网络设备配置管理
系统配置
系统信息
操作系统
uname [options]
选项 | 说明 |
---|---|
-a, --all | 包括以下系统信息: |
-s, --kernel-name | 内核名称(Linux ) |
-n, --nodename | 网络主机名称(使用hostnamectl 设置) |
-r, --kernel-release | 内核发行版本(3.10.0-1160.24.1.el7.x86_64 ) |
-v, --kernel-version | 内核版本(#1 SMP Thu Apr 8 19:51:47 UTC 2021 ) |
-m, --machine | 机器的硬件架构名称(x86_64 ) |
-o, --operating-system | 操作系统(GNU/Linux ) |
-i,--hardware-platform
和-p, --processor
(不可移植),通常与-m
输出一致。
系统版本信息
cat /etc/issue # [Ubuntu]
cat /etc/lsb-release # [Ubuntu]
cat /etc/os-release # [Ubuntu|CentOS]
lsb_release -crid # 包含版本号详细信息,CentOS需要安装redhat-lsb-core
rpm -qa centos-release # [Fedora/CentOS]
rpm -qi basesystem # [Fedora/CentOS](包含安装日期)
操作系统安装时间
通过文件系统创建时间判断操作系统安装时间:
tune2fs -l $(df / | awk '$6 ~ /\// {print $1}') | grep 'Filesystem created:' # -> dumpe2fs
rpm -qi setup|setuptool|basesystem # [Fedora/CentOS]
tune2fs
是设置ext2/ext3/ext4文件系统参数的工具。
主机名
hostnamectl # 显示主机信息(主机名、系统名、架构...)
hostnamectl set-hostname 'gfs.server.03.net' # 设置主机名
sysctl -n kernel.hostname
某些服务(例如Cloudera)需要检测主机名与域名(FQDN)的一致性,为了避免产生警告,将主机名设置为域名。
WSL-Ubuntu中
hostnamectl
不可用。
域名映射
sudo vi /etc/hosts
# change <hosts> file
192.168.137.11 new-host-name
可能需要重启。
日期时间
显示时间
date # Sun May 16 13:07:15 CST 2021
date +'%H' # %T %c %F
date -d,--date='7:00:00' +'%s' # parse a date and display it
date --date='@2147483647' # parse a timestamp (seconds)
date -r,--reference=FILE # 显示文件最近修改时间
默认显示当前时间,使用
-d,--date
指定要显示的时间的字符串;字符串缺少的部分设为当前时间。空字符串表示当天开始时间。
A list of date command field descriptors
获取日期字段
格式声明 | 含义 | 格式声明 | 含义 | 格式声明 | 含义 |
---|---|---|---|---|---|
%Y | YYYY | %m | mm | %d | dd |
%H | HH (00-23) | %M | MM (00-59) | %S | SS |
%s | 时间戳(秒) | %3N | 毫秒 | %N | 纳秒 |
%f | 微秒 |
格式化日期字段
%
后可额外设置表示填充的字符:-
不填充;_
填充空格;0
填充0(默认);^
使用大写字母;#
(尽可能)改变字符大小写。
格式 | 含义 | 格式 | 含义 | 格式 | 含义 |
---|---|---|---|---|---|
%c | locale's datetime | %x | locale' date | %X | locale's time |
%D | %m/%d/%y | %F | %Y-%m-%d | ||
%T | %H:%M:%S | %r | 12:11:04 PM | %X | 23:13:48 (locale) |
%y | yy | %e | %_d | ||
%I | hh (01-12) | %k | _H (0-23) | %l | _h |
%j | ddd : day of year | %w | day of week(0-6) 0 is Sunday | %u | day of week(1-7) 1 is Monday |
%W | week of year(00-53), Monday first | %U | week of year(00-53), Sunday first | %V | week of year(01-53), Monday first |
%p | AM/PM | %P | am/pm | %q | quater 00-04 |
%z | 时区-0400 | %:z | -04:00 | %::z | -04:00:00 |
%Z | 时区类型EDT/CST |
设置时间:
timedatectl [status] # 显示系统的日期、时间和时区等信息
timedatectl set-time "2012-10-30 18:17:16" # <== timedatectl set-ntp no
date -u,--utc=MMDDhhmmCCYY.ss # print or set datetime
date -s,--set=STRING
timedatectl set-timezone <Asia/Shanghai>
timedatectl list-timezones # 列出已知时区
系统启动时间:
uptime
系统引导配置
引导配置文件:
/etc/default/grub
/etc/grub/grub.cfg # auto-generated by grub-update
选择默认用户界面:
sudo systemctl set-default multiuser.target # terminal shell
sudo systemctl set-default graphical.target # GUI
添加开机启动项
-
编辑
/etc/rc.local
脚本(兼容性目的),并设定可执行权限(sudo chmod 755
)适合较短的命令
-
将启动项的脚本添加到
/etc/init.d
目录下,并设置可执行权限ln -s task.sh /etc/init.d/task sudo chmod +x /etc/init.d/task
cd /etc/init.d sudo update-rc.d task defaults 95 # execute order sudo update-rc.d -f task remove # remove the task
如果使用需要开机通过
chkconfig
设置开机启动的服务,则脚本开头应该包含以下信息:#!/bin/bash # chkconfig: 2345 20 80 # description: Saves and restores system entropy pool \ # for higher quality random number generation.
chkconfig: 2345 20 80
表示这个服务在运行级别2345下运行,20表示开机启动优先权重,80表示关闭优先权重。也可以手动调用
chkconfig
添加开机启动服务chkconfig --add my-service
实际上
chkconfig --add
命令是将/etc/init.d
中的启动脚本软连接到/etc/rc.d/rcx.d
(rc0.d ... rc6.d
)0-6个运行级别对应相应的目录,都是位于/etc/init.d
中脚本的软连接。/etc/init.d/
中的脚本,可以通过命令:service service_name [start/stop]
启动或者关闭(添加到启动脚本中实现自启动,见方法1或)。
-
将启动任务的脚本放到目录
/etc/profile.d
下,系统启动后将自动执行其中的shell脚本。 -
注册为
systemd
托管的服务,在系统启动时运行。
内核配置
内核配置项对应文件系统中/proc/sys
目录。
读取内核配置项:配置项具有分级结构(对应上述目录树),名称以.
或/
分隔。
sysctl -n variable # 输出value, 默认输出 variable = value
sysctl -a -pattern PATTERN # 打印所有配置项(某些配置项需要管理员权限才可访问)
-n,--values
:仅打印配置项的值;-N,--names
:仅打印配置项的名称;
sysctl -q,--quiet \ # 不将设置的值回显到屏幕
-w variable=value ...
加载内核配置:
sysctl -p,--load [FILE] # 默认加载/etc/sysctl.conf
sysctl --system # 加载系统中所有配置文件
文件系统
最大打开文件数量限制
ulimit -n 8192 # 默认1024, 临时修改
编辑/etc/security/limits.conf
,永久修改:
# domain type item value
* soft nofile 16384 # soft limits of Number of Open file
* hard nofile 16384 # hard limits
linux - Fix with ulimit -n 8192 - Stack Overflow
inotify
文件监控数量限制
文件监控数量限制如果设置太小,容易触发inotify watch limit reached
错误。临时设置运行时参数:
sudo sysctl fs.inotify.max_user_watches=524288 # 8192 default
永久修改配置(/etc/sysctl.conf
)并运行sysctl -p
重新加载。
fs.inotify.max_user_watches=524288
字体
用户可将字体安装在/usr/share/fonts
目录下,使用fc-list
(需要安装fontconfig
)可查看系统中可用字体。
fc-list # "FONT_PATH: FONT_FAMILY:style=STYLE"
fc-list : family # 仅输出字体名
fc-list :lang=zh family style file spacing # "PATH: FAMILY:style=STYLE:spacing=SPACE"
日志
大部分的发行版都内置使用syslog
系统日志,常见的日志一般存放在 /var/log
中。
常见的系统日志
日志名称 | 记录信息 |
---|---|
alternatives.log | 系统的一些更新替代信息记录 |
apport.log | 应用程序崩溃信息记录 |
apt/history.log | 使用apt 安装卸载软件的信息记录 |
apt/term.log | 使用apt 时的具体操作,如package的下载、打开等 |
auth.log | 登录认证的信息记录 |
boot.log | 系统启动时的程序服务的日志信息 |
Consolekit/history | 控制台的信息记录 |
dist-upgrade | dist-upgrade 这种更新方式的信息记录 |
dmesg | 启动时,显示屏幕上内核缓冲信息,与硬件有关的信息 |
dpkg.log | dpkg 命令管理包的日志 |
faillog | 用户登录失败详细信息记录 |
fontconfig.log | 与字体配置有关的信息记录 |
kern.log | 内核产生的信息记录,在自己修改内核时有很大帮助 |
lastlog | 用户的最近一次信息记录。 |
wtmp | 登录信息的记录。 |
btmp | 远程登录信息记录。 |
syslog | 系统信息记录 |
日志一般都是文本文件,可使用 less
、cat
、more
等工具查看。 wtmp
、lastlog
是二进制文件,需要使用last
和lastlog
工具来提取其中的信息。
rsyslog
systemd-journal
查看日志
筛选日志:
journalctl --system|user # 查看系统/当前用户日志
journalctl -u,--unit=UNIT
-t,--identifier=STRING # 查看指定syslog标识的日志
-S,--since=DATE # '2022-05-01 [12:00:00]'
-U,--until=DATE
追踪日志更新:
journalctl -f,--follow
-n,--lines=NUM # 显示日志数量
日志存储设置
journalctl --disk-usage
journalctl --rotate
journalctl --vacuum-time=2d # 清理超过2天的日志
journalctl --vacuum-size=100M # 清理超过100M的日志
journalctl --vacuum-files=5 # 清理超过数量的日志
systemctl kill --kill-who=main --signal=SIGUSR2 systemd-journald.service
rm -rf /run/log/journal/*
rm -rf /var/log/journal/*
systemctl restart systemd-journald.service
journalctl --verify
终端命令记录
histroy # 显示历史记录: cat ~/.bash_history
history -c # 删除历史记录:rm ~/.bash_history
用户登录信息
who /var/log/wtmp # 查看用户登录历史记录
last [username] [-f /var/log/btmp] # 默认读取/var/log/wtmp
lastlog [-u username] [-t 5] [-b 60]
浏览器(桌面环境)
ls -l ~/.opera/cach4
ls -l ~/.mozilla/firefox/*.default/cache
日志清理
logrotate
是Linux自带的文本日志处理工具,可进行切割、打包、压缩等处理。其配置文件位于/etc/logrotate.conf
以及/etc/logrotate.d/
。
/tmp/dask/*log {
rotate 7 # 指定日志文件删除之前转储的次数,0直接删除,-1不删除
daily # 指定转储周期:hourly,daily,weekly,monthly, yearly
minsize 1M # 文件大于1M时才会进行轮转
maxsize 100M # 文件大于100M时强制进行轮转(即使还未到轮换周期)
size 100M # 指定轮转大小: k/M/G (与轮转周期互斥)
minage 10 # 文件创建超过10天才进行轮转
maxage 100 # 移除创建超过100天的已轮转的文件
missingok # 忽略不存在的日志文件/nomissingok
ifempty # 即使日志文件为空文件也做轮转/noifempty
dateext # 使用当期日期作为命名格式,默认值取决于轮换周期
dateformat -%Y%m%d%H #
nocompress #
create [[mode] owner group] # 新日志文件的权限, 默认和原来的文件相同的权限
copytruncate # 复制并清空日志文件(override create)*
prerotate
script
endscript
postrotate # postrotate脚本
/sbin/nginx -s reload
endscript # postrotate脚本结束
}
*
:适用于日志输出程序无法获取日志文件打开状态的情况;但可能造成少量日志丢失。
logrotate
通过ctrontab
调度,默认每天运行一次(除非任务指定更小的周期)。可手动立即执行:
logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
软件管理
各发行版提供的软件仓库与软件管理方案。本章介绍,当前主要的跨发行版软件管理解决方案。
Snap
Snap将软件及其依赖打包到独立环境,它的运行环境是容器化的沙箱,从而避免各发行版兼容性问题并保证一定的安全性。
安装snap
Ubuntu/Debian系统预装snapd
,使用snap version
查看。
sudo yum install snapd # [epel-release]
sudo systemctl enable snapd # 安装后需要手动启动
snapd
无需持续在后台运行,仅在执行snap
命令时被调用运行。
安装和升级snap软件
snap find "media player"
sudo snapd install 'appname'
sudo snap refresh 'appname' # update
snap list # 列出已安装的软件的简要信息
snap info 'pkgname'| 'pkgname.snap' # 查看[已安装]软件包信息
--color=auto|always|never
--verbose
安装classic
类型的软件,此类软件不受沙盒限制:
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install julia --classic
下载snap
包和离线安装:
snap donwload 'package name'
--target-directory=.
--channel=5.x/stable
snap ack path/to/package_name.assert
snap install path/to/package_name.snap
--dangerous # 如果没有执行ack,则需要该选项才可以安装
snap安装目录
/snap # -> Debian based
#/snap/bin - Symlinks to snap applications.
#/snap/<snapname>/<revision> - Mountpoint for snap content.
#/snap/<snapname>/current - Symlink to current revision, if enabled.
/var/lib/snapd/snap # -> RHEL based
snapying用的配置文件/数据目录
/var/snap/"snap_name"
移除snap软件
snap remove "snap_name"
--purge # 不保存软件的数据
软件的所有数据将自动备份(automatic snapshopt)以便后续恢复。
备份和恢复
snap save 'appname' --users "all" # 创建用户、系统和配置数据的快照。
snap saved --id ID
snap forget "id" "appname"
snap restore "id" "snap_name" --users "all" # 使用指定快照恢复其中的用户、系统和配置数据。
snap export-snapshot "id" /path/to/export
snap import-snapshot /path/to/import
不同版本(
epoch
)之间不能恢复数据。
回退到上个版本并恢复数据(不包括共享数据):
sudo snap revert 'appname' --revision ID
snap配置
snap get "appname"
snap set "appname" key1=value1 key2.subkey=value2
snap unset "appname" key1 key2
管理snap应用的运行状态
查看服务运行状态和日志:
snap services <appaname> # 查看APP提供的服务的运行状态
# => systemctl status snap.<appname>.<appserivce>
snap logs -f <appname>.<servicename>
启动应用软件
如果安装未生成启动软件的快捷方式,可通过命令启动。
snap run <appcommand> # 命令可通过snap info查看
管理软件服务
可使用snap
或systemctl
来控制服务运行。snap
服务默认会在失效后自动重启。
sudo snap start/restart/stop <appname>
sudo snap restart <appname>.<servicename>
sudo systemctl restart snap.<appname>.<servicename>
AppImage
AppImage比较简单易用,不需要安装额外的工具,整个软件都在一个文件里,下载后可以直接运行。里面有个SquashFS的文件系统,运行的时候会挂在到一个临时的地方,里面有所有只读的文件,包括可执行文件、库文件、静态数据等。除此之外都和普通的软件运行环境是一样的。
Similar projects · AppImage/AppImageKit Wiki (github.com)
Flatpak
linuxbrew
安装发行版软件仓库缺失的软件。
安装linuxbrew
SRC_URL='https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh'
/bin/bash -c "$(curl -fsSL $SRC_URL)"
官方安装脚本下载以及官方源(github)的速度都比较慢,推荐使用代理进行安装。或者使用国内镜像进行安装和后续软件安装,配置镜像源相关环境变量:
MIRROR="https://mirrors.tuna.tsinghua.edu.cn"
export HOMEBREW_BREW_GIT_REMOTE="$MIRROR/git/homebrew/brew.git"
export HOMEBREW_CORE_GIT_REMOTE="$MIRROR/git/homebrew/homebrew-core.git"
export HOMEBREW_BOTTLE_DOMAIN="$MIRROR/homebrew-bottles"
执行以下命令下载安装脚本并执行安装:
git clone --depth=1 $MIRROR/git/homebrew/install.git brew-install
bash brew-install/install.sh
rm -rf brew-install
安装完成后根据输出提示,将初始化命令加入shell配置文件。然后,根据输出信息,安装建议的编译环境,用于brew
进行本地编译打包。
brew
的默认安装位置为/home/linuxbrew/.linuxbrew/
。
安装软件
brew install pkgname
查找软件可在brew.sh查找,或通过命令查找:
brew search pkgname
进程管理
查看进程
jobs [-lnprs] [jobspec ...] or jobs -x command [args]
# Display status of jobs.
查看并过滤进程
ps -e|-A \ # 查看所有进程
-T|t \ # 当前终端上的所有进程
-x \ # 没有关联控制终端(tty)的进程
-r \ # 正在运行的进程
-a \ # 排除关联tty的所有进程或session leader
-d \ # 除了session leader外的所有进程
-N \ # --deselect 反选
H # 将线程视作进程显示
查找进程
ps -C cmd1,cmd2,... \ # 根据命令名comm筛选
-p 123,124,... \ # --pid,-q 根据进程号筛选
-ppid 10 \ # 根据父进程号筛选
-U EUID \ # effective user ID (EUID) or name
-u RUID \ # real user ID (RUID) or name
-C
匹配进程命令起始子串,不包括路径与特殊字符'/-
';无法匹配到僵尸进程。
pgrep -f PATTERN \ # --full 匹配完整进程名
-x \ # --exact 完整匹配命令行
-v \ # --inverse 反向匹配
-g PGID,... \ # --pgroup 匹配进程组ID
-G GID,... \ # --group 匹配real group IDs
-i \ # --ignore-case
-n \ # --newest 选择最近启动的进程
-o \ # --oldest
-P PPID,... \ # --parent 匹配父进程ID
-s SID,... \ # --sessioin 匹配会话ID
-u ID,... \ # --euid 匹配effective user ID
-U ID,... \ # --uid 匹配real user ID
-t TTY,... \ # --terminal 匹配终端
--ns PID --nslist ns,...
pgrep -l \ # --list-name 列出PID和进程名
-a \ # --list-full 列出PID和命令行
-c \ # --count 输出匹配计数
ps -C
和pgrep
无法匹配到僵尸进程<defunct>
,可以利用ps -ef
的输出内容进行匹配。
ps -ef | grep defunct | grep -v grep
输出进程信息
ps -f|-F \ # 完全信息,包括命令行(-F包括附加信息)
-l \ # 显示更多信息,可以与-f|-F组合使用
ps -o pid,tid,... \ # 指定输出的字段
-o '%cpu %mem' \ # 在单个参数中指定输出的字段
-o class \ # 可指定多个输出选项
-o wchan:14 \ # 指定输出字段的位宽
-o comm= \ # 该字段不输出字段名(当所有字段都不输出字段名,省略表头)
pid | ==进程编号== | ppid | 父进程编号 |
`lwp | spid | tid` | 轻量线程ID |
`pgid | prp` | 进程组编号 | tgid |
`%cpu | pcpu` | CPU占用率(小数) | c |
`cputime | time` | ==累计CPU占用时长== | pri |
start_time | ==进程启动时间/日期== | start | 进程启动时间 |
etime | ==进程启动后经过的时间== | etimes | 单位为秒 |
`%mem | pmem` | 内存占用比例 | `vsz |
sz | 进程镜像大小 | size | 需要的交换空间大小 |
`args | cmd | command` | 命令行参数 |
`sess | session | sid` | 会话编号 |
`tty | tt | tname` | 控制终端 |
`fgid | fsgid` | 文件访问组编号 | `fgroup |
`state | s` | stat |
进程关联用户信息:
real | effective | saved | ||
---|---|---|---|---|
用户ID | uid | ruid | `euid | uid` |
用户标识 | user | ruser | `euser | user |
组 | gid | rgid | `egid | gid` |
组标识 | group | rgroup | `group | egroup` |
需要systemd支持的字段:
machine
:进程分配到的VM或容器名;ouid
:进程会话所有者;lsession
:进程的登录会话标识;其他:
psr
:为进程分配的处理器,sgi_p
:进程当前运行的处理器;
cgroup
:控制组;
class|cls|policy
:进程调度类型;sched
;
blocked|sig_block|sigmask
:阻止的信号(32或64位掩码);caught|sig_catch|sigcatch
:捕获的信号(32或64位掩码);ignored|sig_ignore, sigignore
:忽略的信号(32或64位掩码);pending|sig
:挂起的信号(32或64位掩码);
f|flag|flags
:进程标识。
进程树
ps f \ # 显示为进程树
-H \ # 显示进程层级(缩进)
pstree -U \ # --unicode 使用UTF-8画线符号(默认)表示树
-A \ # --ascii 使用ASCII画线符号
-h \ # --highlight-all 重点显示当前进程及其祖先进程
-H PID \ # --highlight-pid 重点显示给定进程及其祖先进程
-g \ # --show-pgids 显示进程组标识
-p \ # --show-pids 显示进程标识
-s \ # --show-parents 显示父进程标识
-n \ # --numeric-sort 根据PID对输出排序
-l \ # --long 不截断长行
PID \ # 进程树根节点的PID,默认为1(init/systemd)
USER \ # 显示指定用户的进程树
任务状态
top -b -n N \ # 非交互模式,刷新N次
-o FIELD[-+] \ # 按字段排序:"+"=>DESC; "-"=>ASC
-O # 不执行命令,仅输出可用的排序字段
top
命令显示的是你的程序占用的cpu的总数,也就是说如果你是4核cpu那么cpu最高占用率可达400%,top
里显示的是把所有使用率加起来。在
top
的运行环境中按下键盘的1
,显示每个cpu核的状态。
交互环境命令
排序:M->Mem, N->PID, P->%cpu, T->TIME+
。
watch
watch "ps -ef | grep nginx | grep -v grep" \
-d,--difference \ # 高亮两次更新的差别
-n,--interval seconds \ # 更新周期
watch
的命令参数可包含多条命令,输出结果包含每条命令的输出内容。
查看进程打开资源
打开的文件可能是常规文件、文件夹、库、流、网络文件(套接字、NFS文件)等。
lsof # list open files
lsof /bin/bash
#COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
#mysqld_sa 1597 mysql txt REG 253,0 960472 738200678 /usr/bin/bash
#sh 11503 es txt REG 253,0 960472 738200678 /usr/bin/bash
#bash 16538 yarn txt REG 253,0 960472 738200678 /usr/bin/bash
#bash 63028 yarn txt REG 253,0 960472 738200678 /usr/bin/bash
需要安装
lsof
。
fuser [options] file/fs # identify processes using files or sockets
fuser /bin/bash # 返回使用文件的进程号与使用方式(后缀)
# /usr/bin/bash: 1597e 11503e 13039e 63028e 63030e 64836e
进程控制
创建进程
nohup &
终止进程
如果父进程在子进程之后终止,但子进程终止时父进程没有进行最后的回收工作,子进程残留的数据结构称为僵尸进程。
终止单个进程
kill
向进程发送信号使进程终止,默认信号是-TERM
。
kill [-s sigspec | -n signum | -sigspec] pid ...
kill -l [sigspec]
sigspec
表示信号名,signum
表示信号值。
选项 | 说明 |
---|---|
-l, --list [sigspec] | 列出可发送的信号,如果给出信号名(值), 则将信号名(值)转换为信号值(名) |
-s sigspec -n signum -sigspec | 指定发送的信号,例如:-ABRT,-ALRM,-HUP,-KILL,-STOP,-SEGV, -TERM,-TRAP 。 |
终止匹配名称的进程
killall [-s sigspec | -sigspec] [-e] [-I] [-g] [-i] [-u user] [-v] [-w] name ...
killall –l
选项
选项 | 说明 |
---|---|
-l, --list | 列出可发送的信号 |
-s,--signal sigspec -sigspec | 指定发送的信号 |
-e, --exact | 匹配名称 |
-I, --ignore--case | 匹配名称时忽略大小写 |
-g, --process-group | 向进程所属的进程组发送信号 |
-i, --interactive | 在杀死进程前交互式确认 |
-q, --quiet | 如果没有进程被杀死,不输出信息 |
-u, --user | 仅杀死属于给定用户的进程 |
-v, --verbose | 报告信号是否成功发送 |
-w, --wait | 等待所有被杀死的进程结束 |
终止匹配的进程
pkill [options] --signal SIGNAL PATTERN
终止图形进程
xkill
出现“x
”标志的鼠标,点击需要中止的程序即可。
清理进程
wait -f -n [CH_PID,,,] # 清理子进程
服务
systemd
systemd
(system and service manager),init system (PID=1
2, started by the kernel, to bring up userspace) managing userspace services. (fast and efficient boot-up)
sysvinit
/sbin/init -> ../lib/systemd/systemd
system instance: system.conf and the files in system.conf.d
user instance: user.conf and the files in user.conf.d
"units" of 11 different types. states: active/inactive/activating/decativating/failed
;
Units are named as their configuration files
Processes systemd spawns are placed in individual Linux control groups named after the unit which they belong to in the private systemd hierarchy. /sys/fs/cgroup/systemd/
transaction system: before executing a requested operation, systemd will verify that it makes sense, fixing it if possible, and only failing if it really cannot work.
-
Service:管理控制守护进程及其相关进程;
-
Socket:用于提前创建套接字资源。
-
Target:group units(使用
Requires,After
)。default.target whose job is to activate on-boot services and other on-boot units by pulling them in via dependencies.
graphical.target
/multi-user.target
-
Device:expose kernel devices
-
Mount/Swap:mount points/memory swap(类似于
mount
命令) -
Automount
-
Timer:定时触发其他单元;
-
Path:
-
Slice:分组资源管理;
-
Scope:管理外部进程
信号处理:
SIGTERM
:重启systemd system manager;
SIGINT
(Ctrl+Alt+Del
):If this signal is received more than 7 times per 2s, an immediate reboot is triggered.
SIGHUP
:systemctl daemon-reload
管理器交互命令可以用于管理服务。systemctl
are used to give commands to the manager.
systemctl --version # 查看版本和加载模块
systemctl {start|stop|reload|restart|kill} <service>
systemctl {enable|unmask} --now <service> # 启用并立即启动服务
systemctl {disable|mask} <service> # 禁用/屏蔽服务
systemctl status <service>
systemctl show <service>
systemctl list-unit-files --type {service|target} # 列出已安装单元
systemctl list-units --type {...} # 列出已加载单元
systemctl daemon-reload # 重新加载服务单元配置(不影响现有服务)
此外,
systemdctl
还可用于控制系统systemctl {poweroff|reboot[arg]|suspend|hibernate}
service
命令也用用管理服务,在Ubuntu中其实际调用的是systemctl
。
Systemd 入门教程:命令篇 - 阮一峰的网络日志 (ruanyifeng.com)
管理配置文件
A unit file is a plain text ini-style file that encodes information about a service, socket, device, mount point, automount point, swap file or partition, start-up target, watched file system path, timer controlled and supervised by
systemd
, resource management slice or group of externally created processes.
服务配置文件(.ini
格式)位于/lib/systemd/system
(/lib->/usr/lib
);systemctl enable
会在/etc/systemd/system
目录(某些服务也直接置于*.target
子目录下)创建一个指向服务单元的链接(也可直接在该目录下储存配置文件或链接其他位置的配置文件,但无法使用enable/disable
命令)。
pkg-config systemd --variable=systemdsystemunitdir
:系统服务配置文件路径;
pkg-config systemd --variable=systemduserunitdir
;不同于其他
systemctl
命令,==必须以管理员权限执行==systemctl enable|disable
以创建或删除服务配置文件的链接。
配置文件名由管理单元名和类型名组成,如unit-name[@instance-name].service
(服务模板:在配置文件中通过"%i"
引用实例名称)。文件格式:key=value
,=
前后空格被忽略;#
或;
为注释行;\
用于换行拼接(连接时添加空格,换行符后的注释行被忽略,随后的内容将继续被拼接);
boolean:1,yes,true,on
,0,no,false,off
time:默认为秒,"2min 200ms
", s", "min", "h", "d", "w", "ms", "us".
multiple settings form a list, empty value "resets"
[Unit]
Description=The descript of the service
Documentation=http://,https://,file:,info:,man:,
Wants/Requires/Requisite/BindsTo/PartOf/Upholds=
Conflicts=
Before/After=
After=network.target ... nginx.service mongod.service
[Install]
Alias=sshd.service # create symlinks
WantedBy/RequiredBy=multi-user.target
Unit
和Install
是所有单元类型配置文件共有的部分。
foo.service.d/*.conf
:在该目录下添加配置文件覆盖该服务的默认配置。
单元参数说明:
- 依赖声明:==不影响启动顺序(可并行启动)==
Wants=
:one-time effect=> [Install] WantedBy=
:foo.service.wants/
Requires=
:=> [Install] RequiredBy=
Requisite=
:=> RequisiteOf=
BindsTo=
:=> BoundBy=
PartOf=
:=> ConsistsOf=
UpHolds=
:continuous effect,
Conflicts=
:=> ConflictedBy=
- 启动顺序
Before=, After=
OnFailure=,OnSuccess=
Specifiers available in unit files: https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Specifiers
服务单元参数说明:
[Service]
Type=simple/exec/forking/oneshot/dbus/notify/idle
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c conf/nginx.conf # 启动前的检测
ExecStart=/usr/local/nginx/sbin/nginx -c conf/nginx.conf # 启动服务的命令
ExecStartPost=/bin/sleep 1 # 启动服务后的命令
ExecReload=/usr/local/nginx/sbin/nginx -s reload # reload命令
ExecStop=/bin/kill -s TERM $MAINPID # stop命令
StandardOutput=syslog
User=service_user
Environment="VAR=VALUE" "VAR2=VALUE2"
Environment="VAR3=VALUE3" # 可声明多行环境变量
KillMode=control-group, mixed, process, none
KillSignal=SIGTERM
-
Type=
:服务类型simple
(默认):认为ExecStart=
配置的进程为服务主进程;当服务主进程被创建后(服务执行程序还未运行)即认为服务启动(即使随后服务启动过程出错,systemctl start
仍然报告启动成功)并继续启动后续服务。exec
:等待服务进程被执行后才认为服务启动(systemd
219版本不支持,245版本支持该类型);notify
:类似于exec
,但服务启动后需要发送一个通知消息,服务管理在收到通知消息后,认为服务启动完成并继续启动后续服务;设置NotifyAccess=
以访问systemd
提供的通知套接字。
oneshot
:类似于simple
,服务主进程退出后即认为服务启动完成,通常用于设置==开机启动任务==;RemainAfterExit=yes
用于表示服务在启动完成后进入active
状态,否则,由于没有配置持续运行的进程,服务状态将变为deactivating
或dead
状态。dbus
:类似于simple
,服务获得一个D-Bus总线名(BusName=
)后,即认为完成启动;默认依赖dbus.socket
;idle
:类似于simple
,但会延迟服务程序的执行时间(最多5s),直到活动任务被执行。
forking
:ExecStart=
配置的进程会调用fork()
来启动后台服务(Unix服务启动协议)。父进程在后台进程启动完成后退出,服务管理认为服务启动完成。==如果服务自身可以输出主进程ID到文件,则推荐使用PIDFile=
选项==,使得systemd
能够可靠地识别服务主进程从而判断服务状态 。如果未设置PIDFile
,则默认GuessMainPID=yes
以尝试获取服务主进程ID,但如果服务存在多个守护进程,则不一定准确。
对于长期运行服务,首先推荐使用简单且快速的
Type=simlpe
。但如果需要获取服务启动状态,或其他服务依赖此服务,则推荐使用notify
或dbus
;如果服务程序并不支持notify
或dbus
,则使用forking
。对于==仅启动时执行一次==的服务,则可以使用oneshot
。 -
-
RootDirectory=
(chroot
) -
WorkingDirectory=
-
User=, Group=
-
进程资源限制
ulimit
:LimitCPU/LimitFSIZE/LimitNOFILE...
; -
CPU调度策略:
CPUSchedulingPolicy/CPUAffinity...
-
Environment=,EnvironmentFile=
:定义传递给服务的环境变量(定义不支持Shell变量替换,重复定义将替换之前的定义);$PATH
:默认值/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
;$MAINPID
:服务主进程ID,用于管理服务控制进程的关闭和重载;$PIDFILE
:通过PIDFile=
传递,用于服务守护进程写入进程ID;
-
StandardInput=,StandardOutput=,StandardError=
:inherit, null, tty, kmsg, journal+console, kmsg+console, socket or fd:name.
journal
:发送到journal,输出日志通过journalctl
查看syslog
:发送到系统的syslog服务和journal。file:path
(v236+
),append:path
(v240+
),truncate:path
:输出到指定文件(219版本不支持,对于不支持的版本使用文件重定向标准输出)。
systemd
管理的服务产生的日志可通过journalctl
查看。journalctl [FIELD=VALUE...] \ # 未添加匹配条件则返回所有日志 systemd.journal-fields --options
-
SyslogIdentifier=,SyslogFacility=,SyslogLevel=
-
-
ExecStart=
:服务启动命令。==除非是oneshot
类型==,否则仅能给定一条命令。==命令必须以可执行程序的绝对路径开头==(对于其他Exec
命令也一样)。systemd-path search-binaries-default
:如果返回路径,则表示支持直接使用位于路径的命令名。命令参数支持环境变量替换:
${VARIABLE}
始终解释为一个参数,$VARIABLE
必须与命令行==其他内容使用空格分开==(否则不会展开),展开后会按空白分割为多个参数;支持Systemd定义的
%
特殊变量。--opt1 $VARIABLE1 --opt2=${VARIABLE2} # --opt2=$VARIABLE3 无法完成变量替换
命令中不能包含重定向(
<,<<,>,>>
)、管道(|
)和后台执行(&
)等Shell语法。显式使用bash
命令ExecStart=bash -c 'dmesg | tac'
命令前缀:
-
:记非零错误返回,但处理行为等效于命令成功执行;:
:不替换命令行环境变量;- "
+
"以完整权限执行,不受用户和分组设置限制;
-
ExecStartPre=, ExecStartPost=
:类似于ExecStart=
:,分别在ExecStart=
:前后执行,并可指定多条命令。ExecStart=
仅在ExecStartPre=
执行成功的情况下执行,否则服务启动失败(ExecStartPost=
类似)。ExecStartPre=
不应用于启动长期运行程序(ExecStartPre=
启动进程所创建的子进程会在服务程序执行前被终止)。任何Exec*=
命令执行失败或超时,则会跳转到执行ExecStopPost
(跳过ExecStop=
)。 -
ExecReload=
:服务重新加载配置的一条或多条命令(语法类似于ExecStart=
)。 -
ExecStop=,ExecStopPost=
:停止服务的一条或多条命令。如果未指定,则向服务发送``KillSignal=或
RestartKillSignal=`指定的信号以终止服务进程。 -
TimeoutSec=,RestartSec=,TimeoutStartSec=,TimeoutStopSec=
服务启动/停止超时期限。 -
Restart=no|on-success|on-failure|on-abnormal|on-watchdog|on-abort|always
-
SuccessExitStatus=TEMPFAIL 250 SIGKILL
:成功退出状态,默认包括0
,SIGHUP
,SIGINT
,SIGTERM
和SIGPIPE
。
systemd.service (www.freedesktop.org)
服务沙盒
以下选项用于屏蔽向服务进程暴露的系统资源(需要底层安全机制支持才开启,如ProtectSystem
需要包含文件系统命名空间的内核)。
ProtectSystem=false|true|full|strict*
ProtectHome=false|true|read-only|tmpfs
PrivateTmp=false|true
*
:strict
,tmpfs
在219
版本(CentOS 7)不可用。
- [Mastering systemd: Securing and sandboxing applications and services | Enable Sysadmin (redhat.com)](https://www.redhat.com/sysadmin/mastering-systemd#:~:text=Systemd provides a significant number of security features,this option to full also makes %2Fetc read-only.)
- systemd.exec Sandboxing(www.freedesktop.org)
问题:
-
开启
ProtectSystem
后无法对用户家目录进行写操作。如果使用普通用户运行服务,则不用担心该服务修改系统资源(无权限)。因此,可以关闭
ProctectSystem
选项。也可尝试将服务的写入目录修改为其他位置,例如/tmp
或/var
(适用于以root
运行的服务)。
挂载单元配置
[Mount]
What=/dev/DEVNAME
Where=/mnt/MOUNT_PATH
Type=fs_type
Options=
DirectoryMode=0755 # 自动创建挂载点
TimeoutSec=
# Check systemd.exec(5) and systemd.kill(5) for more settings.
定时单元器配置
[Timer]
OnActiveSec/OnUnitActiveSec= # 相对定时器(执行单元)上次触发时间设置定时器
OnUnitInactiveSec= # 相对定时器执行单元上次休眠时间设置定时器
OnCalendar= # systemd.time(7)
Unit= # 定时器超时后触发的单元名称
supervisor
Introduction — Supervisor 4.2.2 documentation (supervisord.org)
Supervisor is a client/server system that allows its users to control a number of processes on UNIX-like operating systems. It is not meant to be run as a substitute for
init
as “process id 1”. Instead it is meant to be used to ==control processes related to a project or a customer==,
supervisord
starts processes as its subprocesses viafork
/exec
and subprocesses don’t daemonize. It always knows the true up/down status of its children. If supervisord is started as root, it is possible to allow “normal” users to control (“stop”, “start”, and “restart” ) such processes.
client/server system
delegation: Supervisorctl allows a very limited form of access to the machine, essentially allowing users to see process status and control supervisord-controlled subprocesses by emitting “stop”, “start”, and “restart” commands from a simple shell or web UI.
/etc/supervisord.conf
supervisord -c conf_file
-n, --nodaemon
-q ,--childlogdir=PATH # must exist, for auto-mode child proocess
-k, --nocleanup # prevent removal of old AUTO process log files
supervisorctl -c conf_file
-i,--interactive # 启动交互式命令
-r,--history-file # 记录输入命令(realine模块可用)
ACTION args...
ACTION:
add/update NAME[:*]... # activate/update process/group config
remove NAME ... # deactivate process config
clear NAME ... # clear process log
pid [NAME] # get pid of supervisord/subprocess
reload # restart remote supervisord
reread # reload daemon's config without restart
start NAME[:*]... # start process/group (not reread configs)
restart NAME[:*]... # restart process/group (not reread configs)
status [NAME[:*]...] # 返回进程(组)状态
tail [-f] NAME [stdout|stderr] # 输出日志的最后部分
all
用于参数中表示所有进程和分组。
supervisord as a system service
# supervisord service for systemd (CentOS 7.0+)
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/bin/supervisord
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
supervisord
[supervisord]
logfile=$CWD/supervisord.log # (-l,--logfile=FILE)
logfile_maxbytes=50MB # rotate limit (-y,--logfile_maxbytes=BYTES)
logfile_backups=10 # number of rotates (-z,--logfile_backups=NUM)
loglevel=info # (-e,--loglevel=LEVEL)
pidfile=$CWD/supervisord.pid # (-j,--pidfile=FILE)
directory=$PWD # workdir of supervisord daemon (-d,--directory=PATH)
environment=KEY="val",KEY2="val2" # for all subprocess
信号处理:
SIGTERM/SIGINT/SIGQUIT
:supervisord
及其管理的子进程将会关闭。SIGHUP
:关闭所有进程,重新加载配置,并重启所有进程。SIGUSR2
:关闭并重新打开主日志以及子进程日志。
服务进程配置
[program:SERVICE_NAME]
command=/path/to/programname # relative is OK
user=gary # 启动进程的用户
numprocs=1
priority=999 # Lower priorities indicate programs that start first
autostart=true # start with supervisord
autorestart=unexpected # false, unexpected, or true
startsecs=1 # 0不检查是否进程在运行
startretries=3
exitcodes=0 # 正常退出代码(,分隔)
stopwaitsecs=10 # 进程停止等待时间(超时使用SIGKILL强制停止)
stopasgroup=false # 用于停止具有子进程的进程(如Flask调试模式)
stdout_logfile=AUTO # 进程的标准输出文件
stdout_logfile_maxbytes=50MB # 日志文件轮转大小
stdout_logfile_backups=10 # 日志轮转数量限制
stderr_logfile=AUTO # stderr_logfile_maxbytes/stderr_logfile_backups
stdout_syslog=10 # 使用进程名输出到syslog / stderr_syslog
redirect_stderr=false # 将进程的错误输出重定向到supervisord的输出
environment= # 传递给进程的环境变量
directory= # 进程运行的工作目录
服务进程本身不应该以守护进程模式运行。
自动重启:如果
autorestart=unexpected
,则在非手动停止进程的情况下,如果进程退出代码非exitcodes
列出的,则重启该进程。
AUTO
log files and their backups will be deleted when supervisord restarts.输出文件名为可包含变量
group_name
,host_node_name
,process_num
,program_name
和here
的Python字符串表达式。

服务分组:同类型服务;
[group:foo]
programs=bar,baz
priority=999
supervisorctl
访问supervisord
supervisorctl
可访问本地(UNIX套接字)或远程的supervisord
服务(TCP/IP套接字)。
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock # (-s,--serverurl URL)
# serverurl=http://127.0.0.1:9001
username=gary # (-u,--username NAME)
password=gang2019 # (-p,--password)
prompt=mysupervisor # 命令行提示符
使用Web访问supervisord
[inet_http_server]
port=0.0.0.0:9001
username=gary
password=gang2019 # or passord hash: {SHA}82ab876d1387bfafe46cc1c8a2ef074eae50cb1d
重启
supervisor
(使用systemctl
)。
XML-RPC接口
from xmlrpc.client import ServerProxy
server = ServerProxy('http://localhost:9001/RPC2')
server.supervisor.getState()
server.system.listMethods()
server.system.methodHelp('supervisor.shutdown')
子配置文件
[include]
files=/path/filename.conf /path/*.conf foo.conf config??.conf
XML-RPC API Documentation — Supervisor 4.2.2 documentation (supervisord.org)
Supervisor: A Process Control System — Supervisor 4.2.4 documentation (supervisord.org)
Process Monitoring and Events
Supervisor continually emits event notifications, and the subscribed listener will be notified.
provide a mechanism for code to be run (e.g. send an email, make an HTTP request, etc) when some condition related to subprocess state is met.
The event notification protocol is based on communication via a subprocess’ stdin and stdout.
Example Event Listener Implementation
服务管理程序对比
supervisord
主要用于管理用户服务进程,systemd
处理服务管理外,还支持系统中其他对象如外部设备、套接字、定时器等的管理。
systemd
具有启动依赖管理控制功能,可以实现有依赖关系的一组对象的正确启动和运行管理;supervisord
仅支持进程分组,无依赖解析功能。systemd
具有完善的进程资源控制和系统调度策略设置,supervisor
可实现较为简单的资源控制。
supervisord
提供网络访问接口并有可用的Web访问UI,可方便普通用户实现进程管理;systemd
需要管理权限执行管理控制功能。
superivord
发布于2004年,systemd
发布于2010年。systemd
现在为多数Linux发行版的init
程序,因此开箱即用。supervisord
需要以Python库或发行版软件仓库软件的方式进行安装。
对于较为简单的服务进程配置管理,supervisord
和systemd
都能有效实现;对于有远程管理需求的场景,supervisord
提供网络访问接口更适合。对于复杂的服务配置管控需求以及supervisor
不支持的管控对象,使用systemd
更加合适。
网络管理
网络管理工具
net-tools
:包含arp, ifconfig, netstat, rarp, nameif and route
。
ip
:show/manipulate routing, network devices, interfaces and tunnels,代替net-tools
。
NetworkManager
:包含NetworkManager
服务和命令行工具nmcli
、nmtui
等。
与使用
ip
的功能相同,使用nmcli+NetworkManager
将管理功能与用户交互分离。
networkd
NetworkManager
NetworkManager
用于代替已有的配置工具ifconfig
及其配置文件。NetworkManager
作为systemd
服务运行(服务的配置文件为/etc/NetworkManager/NetworkManager.conf
)。
udev
设备管理器发现系统新加入设备,通知NetworkManager
通过D-Bus来检测和初始化配置网络设备实现即插即用(配置信息动态生成并存储于内存中)。
永久配置文件检查(如果未找到配置文件,则尝试从DHCP服务器获取配置信息):
-
etc/sysconfig/network-scripts/ifcfg-*
:后向兼容ifconfig
配置文件; -
/etc/NetworkManager/system-connections/
:NetworkManager
配置文件。
nmcli
是NetworkManger的命令行工具(客户端),nmtui
是对应的终端图形界面工具。
yum install NetworkManaget-tui # nmcli随NetworkManager安装
图形化配置接口:
nmtui edit <ifname> # in CentOS
在修改配置时,不要修改设备(
00:0C:29:BD:83:63 (ens32)
)
网络状态
主机名和域名
hostname
可以读取主机的主机名、域名和对应的IP地址(/etc/hostname
)。
-A
:所有主机名;-s
返回一个短主机名;-f
返回长主机名;-I
:所有IP地址;-i
还首先读取IPv6地址;-d
:DNS域名;
使用
hostnamectl
设置主机名。
域名地址映射*
dig [@dns_server] domain_name
dig -x ip_addr # reverse lookup
nslookup <domain>
支持反向查询
nslookup <ipaddr>
,但查询到的域名不是通常使用的域名,也可能查不到结果。
whois <ipaddr|domain> # sudo apt install whois
查询IP地址/域名==所有者==。
网络接口信息
nmcli # 代替ifconfig
netstat -i # 输出网络接口设备的统计信息;
-ie # => ifconfig
使用ip
工具列出设备参数(type,mtu,qdisc,state,mode,qlen,mac
):
ip link [show] [up|down] [dev eth0] [type bridge] [master br0] # 显示链路信息
ip address ... # 显示链路层以及网络地址信息
使用nmcli
查看网络接口连接:
nmcli c[onnection] [show] --active # summary table
# NAME UUID TYPE DEVICE
# eth0 cb149a11-edae-3f8f-9af1-7dc541e1ac5d ethernet ens32
nmcli connection show <name/id> # interface details
设备未知的接口通常是由于配置文件存在错误。
查看网络设备信息:
nmcli d[evice] [show] # summary table
# DEVICE TYPE STATE CONNECTION
# ens33 ethernet connected ens33
# lo loopback unmanaged --
nmcli device show <device> # device details
网络通信状态信息
netstat -a # 列出tcp,udp和unix协议套接字连接(默认仅显示unix套接字连接) *
-{t|u} # 只列出TCP/UDP连接
-l # 只列出监听中的连接
-p # 列出进程ID和命令名
-e # 列出进程用户和进程文件的Inode编号
-n # 禁用对IP地址/端口的反向域名解析,加快查询速度
*
:需要安装net-tools
包。
示例:
sudo netstat -anp | grep ESTABLISHED # 打印active状态的连接
sudo netstat -anp | grep apache2 # 查看指定服务是否正常运行
通过访问套接字获取连接信息:
ss -n # 禁止解析服务名称
-r # 尝试解析地址端口信息
-a/l # 显示所有/监听套接字信息
-m # 显示套接字内存占用
-p # 显示使用套接字的进程
-e # 显示扩展信息
-i # 显示TCP内部信息
-s # 打印汇总信息
-N,--net=NSNAME # 切换网络命名空间
-f,--family=unix/inet/inet6/link/netlink/vsock
由于网络连接(套接字)是特殊文件,因此可以使用lsof
查看(lsof
用于列举进程打开的文件)。
lsof -i -P -n
-i [addr]
:列出使用互联网地址的文件(套接字);地址格式
[46][protocol][@hostname|hostaddr][:service|port]
-U
筛选使用UNIX套接字的进程。
-P
:禁止将端口号解析为服务名;
-n
:禁止将IP地址解析为主机名或域名。
网络协议统计信息
netstat -s
监控网络通信状态
iftop # apt|yum install iftop => 主机间通信速率
nload # apt|yum install nload => 网络接口通信统计
bmon # apt|yum install bmon => 系统带宽监控
nethogs # yum install nethogs => 进程通信统计
系统监控工具也可以监控网络通信状态的基本参数。
网络可达性检测
ping
:is part of iputils
package。
ping \ # ICMP ECHO_REQUEST
-4|6 \ # IPv4/IPv6
-c count \
-D # print timestamp before each line
-I interface # 设置源地址或源接口名称
tracepath
:is part of iputils
package.
tracepath -4|6 -n|b # n|b 仅打印IP地址/打印主机名和IP地址
网络设备链路管理
网络配置数据
系统中可能存在的网络设备和接口配置文件:
-
ifup/ifdown
(/etc/network/interfaces
) -
networkd
[connection] id=br0_eno1 uuid=ccfcb8fa-5f16-4407-ae6c-1af6c9117265 type=bridge autoconnect=false interface-name=br0_eno1 permissions= timestamp=1650420144 [bridge] stp=false [ipv4] address1=172.28.76.22/24,172.28.76.234 dns=172.28.28.28;223.5.5.5; dns-priority=100 dns-search= method=manual [ipv6] addr-gen-mode=stable-privacy dns-priority=100 dns-search= method=link-local [proxy]
-
ifconfig
(etc/sysconfig/network-scripts/ifcfg-*
)TYPE=Ethernet NAME=eth0 # 应该和配置文件后缀匹配 DEVICE=ens33 # 绑定的设备名 UUID=a016f249-6703-42eb-a207-e40f80de212f # 绑定的设备UUID HWADDR=84:16:f9:03:fd:85 # 绑定的设备MAC(old) IPADDR=192.168.2.203 PREFIX=24 # <-> NETMASK GATEWAY=192.168.178.2 DNS1=223.5.5.5 DNS2=8.8.8.8 ONBOOT=yes BOOTPROTO=static # dhcp|bootp|none|static
-
NetworkManager
(/etc/NetworkManager/system-connections
)
netplan
netplan
在系统启动早期将配置信息解析并提供给系统的网络管理服务(如NetworkManager
)。
- 默认由
systemd-networkd
管理网络设备,其他服务如NetworkManager
可替代其功能。
netplan
配置文件位于 /{lib,etc,run}/netplan/*.yaml
:
- 对于不同目录下的同名配置文件,仅读取最高优先级目录下的文件(
/run>/etc>/lib
); - 对于不同名文件,将按文件名字典顺序读取配置文件,并将新内容追加/覆盖已读取内容。
配置文件格式(YAML):
network: # 网络配置的根节点
renderer: networkd|NetworkManager # networking backend,
ethernets: # 设备分组, 如: ethernet, modem, wifi
ens33: # 设备ID
dhcp4: false
dhcp6: true
addresses:
- 192.168.0.200/24 # IPv4
lifetime: 0
label: "maas"
- "2001:1::1/64" # IPv6
gateway4: 192.168.0.1 #! deprecated
gateway6: "2001:4::1" #! deprecated
routes: # 静态路由*
- to: default # could be 0/0 or 0.0.0.0/0 optionally 默认路由
via: 192.168.0.1 # 默认网关
metric: 100
on-link: true
- to: default # could be ::/0 optionally
via: cf02:de:ad:be:ef::2
nameservers: # 手动地址配置时设置
addresses: [ 223.5.5.5, "FEDC::1" ]
search: [lab, home] #**
match:
macaddress: 52:54:00:6b:3c:58
macaddress: 52:54:00:6b:3c:59 # 修改匹配设备的MAC地址
mtu: 1500 # 修改匹配设备的MAC地址
version: 2
应用配置文件:
sudo netplan generate # 生成后端配置文件
sudo netplan apply # 直接应用配置
sudo netplan try # validate the config and then apply
物理链路管理
创建和删除链路
ip link add \ # 添加虚拟链路
link DEVICE \ # 指定物理设备(某些链路类型无物理设备,如IP-over-IP)
name NAME \ # 默认为物理设备名称
type TYPE \ # 链路类型:bridge,veth,vlan,macvlan,mactap,ip6tnl,gre,...
index ID # 链路编号
其他参数包括:
mtu,address,broadcast,txqueuelen,numtxqueues,numrxqueues,...
。不同类型链路采用不同的数据链路层协议。
ip link delete {dev NAME|group GROUP} type TYPE
nmcli connection add type <type> ifname <ifname> ... # 创建链路
nmcli connection delete <ifname>
配置链路参数
ip link set [dev NAME] [group GROUP] prop VALUE
ip address {add|change|replace} IFADDR dev NAME # 配置IP地址
如果指定了group
则修改设备所属分组,如果未指定设备,则修改分组中所有设备的属性。配置了IP地址的链路能够使用IP协议进行通信。
nmcli connection modify <ifname> [+-]ipv4.addresses 192.168.0.58[/24]
nmcli connection modify <ifname> [+-]ipv4.dns 114.114.114.114
nmcli connection modify <ifname> [-]ipv4.gateway 192.168.0.2
# ipv4.method manual must be supplied with address
nmcli connection modify <ifname> ipv4.method manual \
ipv4.addresses 192.168.0.58/24
nmcli edit <ifname/id> # 交互式编辑模式,查看和编辑配置项
启用和停用链路
nmcli c reload
nmcli c up <interface> # if interface exist
虚拟网桥管理
创建和配置虚拟网桥
ip link add BRIDGE_NAME type bridge
brctl addbr BRIDGE_NAME
nmcli connection add type bridge CONN_NAME BRIDGE_NAME ifname BRIDGE_NAME
Chapter 12. Configuring a network bridge Red Hat Enterprise Linux 8 | Red Hat Customer Portal
将网卡绑定至网桥
ip link set dev IFNAME master BRIDGE_NAME
nmcli connection modify DEVICE_NAME master BRIDGE_NAME
nmcli connection add type ethernet slave-type bridge CONN_NAME DEVICE_NAME ifname IF_NAME master bridge0
虚拟网卡管理
tap网卡
ip tuntap add dev tap1 mode tap
Tap网卡创建是临时的,如果要永久生效,可将上述命令添加到开机启动命令(如rc.local
)。
linux - How to make tap interfaces persistent after reboot? - Super User
防火墙
Linux内核使用Netfilter/iptables过滤包,其中iptables
为用户交互接口(iptable-services
)。
防火墙规则管理
iptables -t,--table TABLE -OP CHAIN rule_spec # 链名为大写,表名为小写
-t TABLE
:指定访问的表(省略则查看filter
表);
-OP CHAIN
:指定访问的链(省略链名则查看所有链)及其操作(例如-L FORWARD
);
查询规则
iptables -t TABLE -L,--list CHAIN -v -n --line-number -x # 列出所有规则
iptables -t TABLE -C,--check CHAIN RULE_SPEC # 检查指定规则是否存在
-n
:不反向解析IP地址(显示IP地址而非域名,加快速度);
--line,--line-number
:显示规则编号;
-v
:显示更多信息(分组数、字节数等);
-x
:显示精确的计数,而非经过单位转换的数据。
管理规则
iptables -I,--insert CHAIN [NUM] RULE -j TARGET # 在表首部插入一条规则
iptables -A,--append CHAIN RULE -j TARGET # 在表尾部插入一条规则
iptables -R,--replace CHAIN NUM RULE -j TARGET # 替换指定编号的规则
iptables -D,--delete CHAIN RULE -j TARGET # 删除匹配条件的规则
iptables -D CHAIN NUM # 删除指定编号的规则
iptables -F,--flush CHAIN # 清空表中的规则
默认的表为
-t filter
。
添加相同的规则不会覆盖已有规则,可用以下命令修改已有规则的动作:
iptables -t filter -R INPUT 2 <rules> -j <traget> # 修改指定规则的动作
必须指定要修改规则的条件,否则该规则的条件将变为默认值(例如IP将变为
anywhere
)。
修改默认策略
iptables -t filter -P FORWARD DROP
黑白名单机制
黑名单:将默认策略设置为ACCEPT
;在规则中添加阻止策略。
白名单:将默认策略设置为DROP
,在规则中添加允许策略。
默认策略设置为
DROP
的缺点:在对应的链中没有设置任何规则时,管理员也会把自己拒之门外;即使对应的链中存在放行规则,当不小心使用"iptables -F
"清空规则时,放行规则被删除,则所有数据包都无法进入。所以,如果想要使用"白名单"的机制,最好将链的默认策略保持为"ACCEPT
",然后将"拒绝所有请求"这条规则放在链的尾部,将"放行规则"放在前面,这样做,既能实现"白名单"机制,又能保证在规则被清空时,管理员还有机会连接到主机。
自定义链
自定义链仅对应一种类型的表,自定义链中规则配置方式与默认链相同。
iptables -t filter -N,--new-chain IN_WEB # 创建用于filter表的自定义链
iptables -E,--rename-chain IN_WEB WEB # 重命名
iptables -X,--delete-chain WEB # 删除自定义链,需未被引用且不包含任何规则
iptables -t filter -I INPUT RULE -j IN_WEB # 引用自定义链
保存规则
通过iptables
对规则的修改并非永久生效,当重启iptables
服务或者重启服务器以后规则便失效了。如果想要修改永久生效,必须使用service iptables save
保存规则,如果误操作了规则但是并没有保存,那么使用service iptables restart
命令重启iptables
以后即恢复修改前的状态。
目前的发现版多数已用防火墙软件(如
CentOS/firewall
、Ubuntu/ufw
)代替了iptable-services
了,因此使用上述方法需要安装该服务。
iptables-save # 将防火墙规则导出到标准输出
iptables-restore # 从标准输入导入防火墙规则
包匹配条件
多个条件之间具有AND
关系,使用!
对条件取反。
基本匹配条件:
# IP地址
-s sip1,sip2 -d dip1
-s ip/mask
# 协议类型
-p tcp # all, tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh
# 网卡接口
-i eth0 -o eth1
-i
选项只能用于上图中的PREROUTING
链、INPUT
链、FORWARD
链;-o
选项只能用于FORWARD
链、OUTPUT
链、POSTROUTING
链。
扩展匹配条件:由netfilter
的扩展模块处理的条件。
# 端口
-m tcp --sport 1:1024 --dport 22 # 需要指定扩展模块tcp, udp, icmp
-m tcp --sport :1024 --dport 10000: # 可省略一个端口边界参数
-m multiport --dports 22,36,80:100
# IP范围
-m iprange --src-range 192.168.1.127-192.168.1.146 # --dst-range
# 字符串:匹配报文中包含的字符串
-m string --algo bm --string xyz
# time
-m time --datestart 2017-12-24 --datestop 2017-12-27
-m time --timestart 09:00:00 --timestop 18:00:00
-m time --weekdays 6,7 --monthdays 22,23
当扩展模块的名称与协议名称相同的情况下,如果已经指定了协议,则可以省略模块选项。
--algo
指定字符串匹配算法,可选算法有bm
与kmp
。
# connlimit 限制连接数量
-m connlimit --connlimit-above 2 --connlimit-mask 24 -j DROP
--connlimit-mask
表示对一个网段施加连接数限制(未指定时为对每个IP的连接数进行限制)
# limit 使用令牌桶限制报文速率
-p icmp -m limit --limit 10/minute -j ACCEPT
-p icmp -m limit --limit-burst 3 --limit 10/minute -j ACCEPT
--limit
:报文允许的速率(令牌的生成速率,单位可以是second
,minute
,hour
,day
);--limit-burst
:允许的突发流量(令牌桶的容量,默认值为5);需要添加一条默认
DROP/REJECT
的规则,以丢弃超过速率限制的包。
其他扩展条件:tcp-flags
、state
http://www.zsythink.net/archives/1578
动作
REJECT
可以附加发送一个ICMP响应报文。
-j REJCT --reject-with icmp-host-unreachable
-j LOG --log-prefix "logname" --log-level alert
LOG
动作默认将报文的相关信息记录在/var/log/message
文件中,通过修改/etc/rsyslog.conf
(或/etc/syslog.conf
),kern.warning /var/log/iptables.log
--log-level
:emerg
,alert
,crit
,error
,warning
,notice
,info
,debug
。
端口管理
sudo vi /etc/sysconfig/iptables
端口权限
小于1024的端口号(特权端口)不允许非root用户打开,以防恶意程序占用这些端口建立恶意服务。
如果用户需要使用这些端口,解决方法包括:
-
使用Apache或nginx作为代理服务器;
-
使用iptables设置防火墙规则,使得低端口在内部自动转发至高端口;
-
jsvc
-
authbind
-
sudo setcap CAP_NET_BIND_SERVICE=+eip /path/to/binary
路由配置
转发功能
开启防火墙的转发功能。
echo 1 > /proc/sys/net/ipv4/ip_forward # 设置为1开启转发,0关闭转发
sysctl -w net.ipv4.ip_foward=1
上述方式为设置系统运行时变量,要永久生效需要修改系统配置。
Ubuntu使用
ufw
管理防火墙规则,其配置文件在/etc/ufw/sysctl.conf
,其中对应的配置项为:net/ipv4/ip_forward=1 net/ipv6/conf/default/forwarding=1 net/ipv6/conf/all/forwarding=1
CentOS7中配置
/usr/lib/sysctl.d/00-system.conf
,并设置net.ipv4.ip_forward=1
。
设置防火墙转发规则:
iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
NAT
# SNAT: 将源内网地址映射到公网地址
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j SNAT --to-source 192.168.1.146
# 动态SNAT: 动态将源内网地址映射到动态变化的公网地址
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
# DNAT: 将目的公网地址+端口映射到内网地址+端口
iptables -t nat -I PREROUTING \
-d 192.168.1.146 -p tcp --dport 3389 -j DNAT --to-destination 10.1.0.6:3389
DNAT在理论上只配置DNAT规则即可,但是如果在测试时无法正常DNAT,可以尝试增加对应的SNAT,此处按照配置SNAT的流程进行。
如果没有动态SNAT的需求,没有必要使用
MASQUERADE
,因为SNAT更加高效。
本机端口转发
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 # INPUT
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8080 # LOCAL
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1186 -j DNAT --to-destination 127.0.0.1:1186
将访问本机80端口的请求重定向到本机的8080端口(修改目标端口)。
如果要从外部访问本机localhost
监听的端口,可使用DNAT将地址和端口映射到本机换回地址和相应端口(需要开启本地换回路由:sysctl -w net.ipv4.conf.<ifname>.route_localnet=1
,ifname
为输入网络接口)。
路由表
获取路由信息
ip {r|route}
#default via 192.168.178.2 dev ens32 proto static
#default via 172.28.76.234 dev ens33 scope link metric 1
#172.28.76.0/24 dev ens33 proto kernel scope link src 172.28.76.234
#192.168.178.0/24 dev ens32 proto kernel scope link src 192.168.178.40
表格形式:
route [-nee]
#Destination Gateway Genmask Flags Metric ... Iface
#0.0.0.0 192.168.178.2 0.0.0.0 UG 0 ... ens32
#0.0.0.0 172.28.76.234 0.0.0.0 UG 1 ... ens33
#172.28.76.0 0.0.0.0 255.255.255.0 U 0 ... ens33
#192.168.178.0 0.0.0.0 255.255.255.0 U 0 ... ens32
netstat -r -n
#Kernel IP routing table
#Destination Gateway Genmask Flags MSS Window irtt Iface
#0.0.0.0 172.28.76.234 0.0.0.0 UG 0 0 0 ens33
#172.28.76.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33
ee
:显示更多信息。
-
路由类型
主机路由:掩码为32位; 网络路由: 默认路由:目标为
0.0.0.0/0.0.0.0
。当主机不能在路由表中查找到目标主机的IP地址或网络路由时,数据包就被发送到默认路由(默认网关)上。 -
Flags说明:
U
(route is up):活动路由;H
(target is host):目的地址是主机;G
(use gateway): 需要网关转发; -
Metric
:路由距离,到达指定网络所需的中转数。 -
Iface
: 当前路由会使用哪个接口来发送数据
配置静态路由
route [add|del] [-net | -host] target [netmask Nm] [gw Gw] [[dev] If]
route add default gw 192.168.1.1
route add -net 5.0.0.0 netmask 255.0.0.0 reject # 设置到指定网络为不可达
没有修改已有路由的命令(例如修改metric),需要先删除再添加一条。
上述命令仅在当前运行环境中有效,要永久保存需要将其添加至文件中。可直接在在/etc/rc.local
中添加上述命令,则开机会自动添加静态路由,但如果开机状态下重启网络服务则不会再次执行/etc/rc.local
,导致静态路由失效。
另一种方式是编辑/etc/sysconfig/static-routes
(CentOS/Fedora),该文件由网络服务自动加载。
any -net 192.56.76.0 netmask 255.255.255.0 dev eth0
由
any
开头的行将被解释为静态路由项。Ubuntu静态路由配置?
ip
工具包用于替换route
等管理工具:
ip route {add|del|change|append|replace} ROUTE
# ROUTE= [TYPE] NETWORK/MASK [via [FAMILY] GW_IP] [dev DEVICE] [weight NUM]
ip route add default via 192.168.1.1 dev eth0 # 设置默认路由
TYPE
:路由类型,包括unicast,mulitcast,broadcast,nat,local,...
;
FAMILY
:协议族: inet,inet6,mpls,bridge,link
;
本地网络代理
可配置系统范围(/etc/environment
)或用户范围(~/.bashrc
或~/.profile
)。
export http_proxy="http://USERNAME:PASSWORD@proxy.server.net:port/"
export https_proxy="http://proxy.server.net:port/"
export ftp_proxy="http://proxy.server.net:port/"
export no_proxy="localhost, 127.0.0.1, 192.168.178.4" #*
*
:no_proxy
不支持通配符,如果要写一个网段,只能逐个地址列出。no_proxy
主要用于匹配域名后缀,而非IP地址(前缀)。
如果是系统范围代理,还需设置/etc/sudoers.d/proxy
,避免环境变量被覆盖。
Defaults env_keep+="http_proxy https_proxy no_proxy"
网络服务
systemctl restart networking
常用网络服务
远程访问
X-Window
https://wiki.ubuntu.org.cn/%E7%90%86%E8%A7%A3_Xwindow
安全
内核强制访问控制
Both SELinux and AppArmor supports the Type Enforcement security model, which is a type of mandatory access control, based on rules where subjects (processes or users) are allowed to access objects (files, directories, sockets, etc.).
Implementing Mandatory Access Control with SELinux or AppArmor in Linux (tecmint.com)
Security Enhanced Linux
SELinux支持更强的访问控制。
查看SELinux状态:
getenforce
sestatus -v
临时关闭(设置成permissive
模式,仅产生日志不进行控制):
sudo setenforce 0 # setenforce 1 => enforcing mode
永久关闭:
# sudo vi /etc/selinux/config
SELINUX=disabled # SELINUX=enforcing|permissive|disabled
SELinux策略
查看boolean
策略状态:
getsebool -a [se_boolean_entry]
设置boolean
策略:
setsebool -PV se_bool_entry value # (1|true|on,0|false|off)
Apparmor
AppArmor是与SELinux类似的一个访问控制系统,通过它你可以指定程序可以读、写或运行哪些文件,是否可以打开网络端口等。
linux内核强制访问控制--Apparmor - 运维之路 (361way.com)
AppArmor与SELinux - 运维之路 (361way.com)
数字证书
安装证书
系统信任证书目录位于/usr/local/share/ca-certificates
。将证书文件置于该目录下,并将权限设置为644
。
sudo apt install ca-certificates
sudo update ca-certificates # needs super user privilege
生成证书和私钥
OpenSSL是一个非常有用的开源命令行工具包,可用于 X.509 证书,证书签名请求(CSRs)和加密密钥。
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
openssl x509 -in cert.pem -text -noout # 查看证书结构信息
key.pem
为私钥;cert.pem
为证书(包含公钥);生成签名过程设置的密码是在使用密钥的时候使用。使用私钥和证书需要输入制作时设置的密码。
详细步骤
Create an RSA Keypair:
sudo apt install openssl
openssl genrsa -des3 -passout pass:PASSWORD -out keypair.key 2048
Extract the Private Key:
openssl rsa -passin pass:PASSWORD -in keypair.key -out private.key
Creating a “Certificate Signing Request” or CSR
File:
openssl req -new -key private.key -out service.csr
Creating the Certificate “.crt
” File:
openssl x509 -req -days 365 -in service.csr -signkey private.key -out service.crt
https://www.rosehosting.com/blog/how-to-generate-a-self-signed-ssl-certificate-on-linux/
https://www.linux.com/tutorials/creating-self-signed-ssl-certificates-apache-linux/
SSL/TLS
权限管理
用户管理
创建用户
useradd -m -c "FULL NAME" -g GROUP USERNAME # [lowlevel]
adduser --home DIR --shell SHELL --ingroup GROUP USERNAME
adduser
在Debian系发行版上重新封装了底层useradd
命令,其他发行版上是useradd
的别名。以下均为useradd
选项。有效用户名模式:
[a-z_][a-z0-9_-]*[$]?
,长度不超过32。
-c "COMMENT"
:通常用于设置用户名全称;
-s,--shell SHELL
用户的登录shell程序,/etc/default/useradd#SHELL
(chsh
)。
用户目录
-b,--base-dir BASE_DIR
:用户主目录的根目录路径,默认值为/etc/default/useradd#HOME=/home
;-d,--home-dir HOME_DIR
:用户主目录路径,默认值为$BASE_DIR/USERNAME
;- 使用
-m,--create-home
保证创建用户目录;-M,--no-create-home
不创建用户目录(通常用于运行系统服务的非登录用户);
用户组
-g,--gid GROUP
:用户的初始登录组(primary group:ID或名称,必须存在)。 如果未指定该选项,默认(/etc/login.defs#USERGROUPS_ENAB=yes
)会自动创建与用户名同名的组(等效于指定-U,--create-user-group
选项);如果USERGROUPS_ENAB=no
,则新用户的主要组设置为/etc/default/useradd#GROUP=100
。-G,--groups groupname[,...]
:将用户添加至组(supplementary groups);
账户和密码有效性
-f,--inactive DAYS
:密码过期后账户被禁用前的天数。-e,--expiredate YYYY-MM-DD
:账户失效(禁用)日期,默认值为/etc/default/useradd#EXPIRE=''
(不失效);
修改用户
使用usermod
修改用户属性(多数属性对应的选项与useradd
相同)。
usermod -a,--append -G GROUPNAME # 将用户添加到supplementary groups
usermod -l,--login NAME # 修改登录名
usermod -m,--move-home -d,--home HOME # (移动)修改用户主目录
设置账户有效期限
usermod -e,--expiredate YYYY-MM-DD/N/-1 USER # 设置失效日期*
chage -E,--expiredate YYYY-MM-DD/N/-1 USER
*
:N
表示自1970年1月1日的天数。
此外,账户密码失效后账户也会处于失效状态。
设置和更新密码
创建用户时默认禁用密码。使用passwd
设置和更新密码(root
账号可修改普通用户的密码,用户忘记密码可通过root
帐号使用passwd
指令来处理即可)。
passwd username
usermod -p,--password ENCRYPT_PASSWORD
passwd -d,--delete # 删除(置空)用户密码
如果
root
帐号忘记了,可以进入单人维护模式,此时系统会给予提供root
权限的bash
接口,再用passwd
修改密码;或者利用Live CD开机后挂载根目录去修改/etc/shadow
,将root
的密码删除,重新开机后再用passwd
设置新密码。
密码有效期配置
passwd -e,--expire # 立即使用户密码失效, 用户必须在下次登录时重设密码
passwd -x,--maxdays DAYS USER #->chage -M 密码有效期天数(99999/-1)*
passwd -i,--inactive DAYS USER #->chage -I 密码失效后禁用账户前的天数(never)
passwd -n,--mindays DAYS USER #->chage -m 两次修改密码之间至少相隔的天数(0)
passwd -w,--warndays DAYS USER #->chage -W 需要修改密码前向发送警告的天数(7)
*
:chage
的长选项与passwd
对应长选项一致。
显示密码状态:
passwd -S <user> # 使用-a代替<user>查看所有用户的密码状态。
# gary P 06/02/2022 0 99999 7 -1
chage -l <user>
# Last password change : Jun 02, 2022
# Password expires : never
# Password inactive : never
# Account expires : never
# Minimum number of days between password change : 0
# Maximum number of days between password change : 99999
# Number of days of warning before password expires : 7
删除用户
userdel -f $USER # deluser [Debian]
rm -rf /home/$USER
查看用户信息
查系统中的用户信息:
/etc/passwd # User account information.
/etc/shadow # Secure user account information. [read by root only]
查看当前登录的所有用户:
w
# 09:42:35 up 26 min, 3 users, load average: 0.18, 0.12, 0.09
#USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
#root pts/0 172.28.76.41 09:17 3.00s 0.13s 0.03s w
#root pts/1 172.28.76.239 09:19 22:45 0.02s 0.02s -bash
who
显示的信息没有w
完整。who
可以显示系统引导终端(tty1
)。
查看指定用户信息:
id $USER
# uid=1000(gary) gid=1000(gary) groups=1000(gary),...(secondary groups)
groups $USER # 查看用户所属组
username=$(whoami) # return user name
sudo whoami # -> root
组管理
groupadd groupname
groupdel groupname
addgroup [options] [--gid ID] group
sudo usermod -g groupname username # change user's primary group
sudo usermod -a -G group[,...] username # add user to a secondary group
adduser user group # add user to grpup
If you omit the
-a
option, the user will be removed from any groups not listed after the-G
option.
sudo gpasswd -d username groupname # Remove a User From a Group
查看组信息
/etc/group # Group account information.
/etc/gshadow # Secure group account information.
访问权限控制
访问权限
修改用户访问文件的权限:
chmod [ugoa][+-=][rwxXstugo],... FILE ...
chmod OCTAL-MODE FILE ...
ugoa
分别代表文件所有用户,文件同组用户,其他用户和所有用户(省略则默认为a
,umask?);+-=
表示增加、删除和设置权限。
权限模式:rwxXst
中的一个或多个,或ugo
中的一个
标识 | 说明 | 标识 | 说明 | 标识 | 说明 |
---|---|---|---|---|---|
r | 读文件 | w | 写文件 | x | 访问/执行 |
s | 设置用户或组 | t | 限制删除 | X | * |
u | 授予所有者权限 | g | 授予组用户权限 | o | 授予其他组权限 |
*
:X
表示仅当目标为目录或已经具有其他用户执行权限时,才设置该目标的访问/执行权限。
OCTAL-MODE
为1~4数字(取值范围0~7,3bit),第一位代表(设置用户ID,设置组ID和限制删除),其余三位数字分别代表ugo
对应的rwx
权限。
Ownership
获取对象的所有者信息:
ls -l /opt/360es/ | awk '{print $3,$4}' # 根据字段位置确定
ls -l /opt/360es/ | sed -n '2,$p' | awk '{printf "user=%s,group=%s\n",$3,$4}'
stat /path/file --format="user=%U group=%G"
从外部(互联网)获取的文件(档案),其所有者信息非本机用户,因此导致本机用户无法正常访问文件,所以需要修改文件的所有者/组。
chown -hR owner[:group] FILE
chgrp
--dereference
:影响符号链接指向的文件而非符号链接;-h,--no-dereference
相反;--from=CURRENT_OWNER:CURRENT_GROUP
:仅当文件的当前属性匹配才进行修改;--reference=RFILE
:使用RFILE
的属性作为修改后的属性;-R
:递归修改。符号链接指向的文件夹的遍历规则根据以下选项决定:
-H
:遍历命令行参数为符号链接锁指向的文件夹;-L
:遍历所有符号链接指向的文件夹;-P
:步遍历符号链接指向的文件夹(默认)。
提升权限
切换登录用户
su - username # switch user
不支持切换到非登录用户。
以管理员身份运行
sudo \
-u, --user=user \ # 指定用户执行输入的命令
-i,--login \ # 使用指定用户登录shell
[command] # 运行命令(未指定则切换终端用户)
当前多数发行版默认禁用root
账户,并以安装系统期间创建的账户作为管理员。管理员需要使用sudo
命令并提供密码以暂时获得root
账户权限(使用sudo
命令创建的文件其所属用户和组为root
)。将其他用户加入sudo
用户组使其具有运行sudo
的权限。如果要恢复root
账户(不推荐),为其设置密码:
sudo passwd root
帮助文档
Linux Manual
- 可执行程序和Shell命令;
- 系统调用函数文档;
- 库函数文档;
- 特殊设备文件(通常位于
/dev
); - 系统内置文件格式和规范(如
/etc/passwd
); - 游戏;
- 其他,如
man(7)
; - 系统管理命令(管理员使用);
- 内核过程(非标准)。
急救模式
emergency mode
进入急救模式
-
GRUB系统选择界面按
e
进入启动配置项编辑模式;linux16 /vmlinuz-.... # 添加rd.break
-
按
Ctrl+X
进入急救模式。
修复磁盘
修复XFS文件系统
由于突然断电,导致XFS文件系统数据损坏。
ls -l /dev/mapper # 找到dm-0对应的挂载点并卸载设备
umount /dev/mapper/centos-root
xfs_repair -L /dev/mapper/centos-root # 修复该设备
init 6 # 成功修复后重启设备