基础字符匹配

语法说明示例
abc匹配连续字符 “abc”abc → “abc”
[abc]匹配 a、b 或 c 中的任意字符[ae] → “a”(在 “apple” 中)
[^abc]匹配 a、b、c 的字符[^ap] → “l”(在 “apple” 中)
[a-z]匹配任意小写字母[a-c] → “a”、“b”、“c”
.匹配任意单个字符(换行符除外)a.c → “abc”、“aac”

预定义字符类

语法说明等价写法
\d数字(0-9)[0-9]
\D数字[^0-9]
\w单词字符(字母、数字、下划线)[a-zA-Z0-9_]
\W单词字符[^\w]
\s空白字符(空格、制表符、换行符)[ \t\n\r]
\S空白字符[^\s]

边界匹配

语法说明示例
^字符串开始^abc → “abc”(需在开头)
$字符串结束end$ → “end”(需在结尾)
\b单词边界\bcat\b → “cat”(不匹配 “catalog”)
\B单词边界\Bcat\B → “cat”(在 “scatter” 中)

重复匹配

语法说明示例
*匹配 0 次或多次a* → “”、“a”、“aa”
+匹配 1 次或多次a+ → “a”、“aa”(不匹配空)
?匹配 0 次或 1 次a? → “”、“a”
{n}匹配 n 次a{3} → “aaa”
{n,}匹配 至少 n 次a{2,} → “aa”、“aaa”
{n,m}匹配 n 到 m 次a{2,4} → “aa”、“aaa”

贪婪模式(默认):尽可能多匹配(a.*b 在 “axbxb” 中匹配整个字符串)。
非贪婪模式:加 ? 尽可能少匹配(a.*?b → “axb”)。


分组与捕获

语法说明示例
(exp)捕获分组,后续可引用(abc)+ → “abcabc”
(?:exp)非捕获分组(不存储)`(?:abc)
\n引用第 n 个分组(a)\1 → “aa”(匹配连续两个相同字符)
(?<name>exp)命名分组(通过名称引用)(?<num>\d+) → 捕获数字并命名为 “num”

注:在真实大数据场景中,非捕获分组通常更快更可靠。


选择与断言

语法说明示例
``逻辑
(?=exp)正向先行断言(后面是 exp)a(?=b) → “a”(仅当后跟 “b” 时)
(?!exp)负向先行断言(后面不是 exp)a(?!b) → “a”(当后跟非 “b” 时)
(?<=exp)正向后行断言(前面是 exp)(?<=a)b → “b”(仅当前有 “a” 时)
(?<!exp)负向后行断言(前面不是 exp)(?<!a)b → “b”(当前不是 “a” 时)

转义与特殊字符

  • 元字符需转义:\.\*\(\)\[\\ 等。

  • 特殊序列:

    • \t:制表符
    • \n:换行符
    • \r:回车符
    • \x21:十六进制字符(如 !
    • \u4E00:Unicode 字符(如 “一”)

标志(Flags)

标志说明示例(全局搜索)
i忽略大小写/aBc/i → “abc”、“ABC”
g全局匹配(所有结果)a 在 “aaa” 中匹配 3 次
m多行模式(^/$ 匹配每行)^a 匹配每行开头的 “a”
s单行模式(. 匹配换行符)a.c → “a\nc”(当 s 启用)

常用正则示例

邮箱验证

1
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

URL 提取

1
https?://[^\s/$.?#]+\.[^\s]+

日期匹配(YYYY-MM-DD)

1
\d{4}-\d{2}-\d{2}

中文汉字

1
[\u4e00-\u9fa5]

工具与学习资源

掌握正则表达式可大幅提升文本处理效率!建议从实际案例入手练习,逐步熟悉复杂语法。

本文参考:

Python概述

pycharm常用快捷键:

作用快捷键作用快捷键
单行注释Ctrl + /复制当前光标所在行Ctrl + D
格式化代码Ctrl + Alt + L删除当前光标所在行Ctrl + X
全局查找Ctrl + Shift + R返回至上次浏览的位置Ctrl + Alt + left/right
快速选中代码Ctrl + W替换Ctrl + R

标识符与关键字:

标识符

标识符就是一个名字,就好像每个人都有自己的名字;主要作用是作为程序中变量、函数、类、模块以及其他对象的调用名称。

Python中标识符的命名要遵守一定的命名规则:

  • 标识符由字母、下划线和数字组成,但不能以数字开头。

  • 标识符不能和 Python中关键字等相同。

  • 标识符严格区分大小写,例:Corazon和corazon是不同标识符。

  • 以下划线开头标识符往往有特殊含义。

关键字

关键字就是Pytnon内部已经定义好的具有特殊意义的标识符,开发人员不能重复定义。

Python3的关键字可以通过keyword模块的变量kwlist查看:

1
2
3
4
5
6
7
8
# 打印关键字列表
import keyword
print(keyword.kwlist)
# 关键字输出结果
['False', 'None', 'True', '__peg_parser__','and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

# 查看关键字帮助
print(help("if"))

定义变量

1
变量名 = 数据

等号表示赋值运算符,两端有空格是开发规范,可以没有。

定义变量示例:

1
2
3
4
5
6
7
8
9
name  =  "Corazon"
age = 35
is_man = True

# 打印单个变量值,print()是一个输出函数,类似Linux里echo
print(name)
print(age)
# 打印多个变量值,多个变量用逗号隔开
print(name, age, is_man)

注释

注释是编写程序时,程序员对一个语句、程序段、函数等的解释或提示,可提高程序代码可读性;

合理的代码注释应该占源代码的1/4左右,注释内容不会被解释器执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 单行注释信息:以#号开头,后面留一个空格
# 这里就是单行注释,以#开头,后面整行都不会被解释器执行
print("I am Corazon teacher.") # 表示打印输出
-- 在程序尾部注释,“#”前至少有两个空格
# 多行注释信息:包含在3个双引号或者3个单引号内的语句
"""
这里就是多行注释
三个引号里面的任何内容不会被解释器执行
"""
或者
'''
这里就是多行注释
三个引号里面的任何内容不会被解释器执行
'''

python代码编写语法规范

代码语句分隔符号

Python使用分号,用于一条语句的结束标识,如果是一行结尾,可用换行来替代分号。

1
2
3
4
5
6
7
8
Python使用分号,用于一条语句的结束标识,如果是一行结尾,可用换行来替代分号。

# 使用分号作为语句分隔符
print("I am");print("Corazon")

# 使用换行作为语句分隔符
print("I am")
print("Corazon")

代码语句缩进要求

Java、C 语言采用大括号“{}”分隔代码块,而Python 采用冒号“:”和“代码缩进”和来区分代码块之间的层次;对于类、函数、流程控制语句、异常处理语句等,行尾的冒号和下一行的缩进,表示下一个代码块的开始;而缩进的结束则表示此代码块的结束。

Python 中可使用空格或者Tab键实现,但无论是手动敲空格,还是使用 Tab 键,通常情况下都是采用 4 个空格长度作为一个缩进量;

默认情况下,一个 Tab 键就是4 个空格。

1
2
3
4
5
6
i = int(input("请你输入一个数字: "))
if i > 5:
print("你输入的数字是", i, ",大于5,",sep='')
else:
print("你输入的数字是", i, ",小于5,",sep='')

代码语法规范补充

Python 采用 PEP 8 作为编码规范,其中 PEP 是 Python Enhancement Proposal(Python 增强建议书)的缩写;8 代表的是 Python 代码的样式指南。

  • 下面仅给大家列出 PEP 8 中初学者应严格遵守的一些编写规则:

  • 不要在行尾添加分号";"

  • 不要用分号将两条命令放在同一行;

  • 在运算符两侧、函数参数之间以及逗号两侧,都使用空格分隔;

  • 使用必要的空行可以增加代码的可读性,通常在顶级定义(如函数或类的定义)之间空两行,而方法定义之间空一行;

  • 另外在用于分隔某些功能的位置也可以空一行。

  • python中有些特殊语句指令结尾,需要加入:

python数据类型介绍

在python开发过程中,可以将数据类型分为两个大类:

python基本数据类型:字符串 数值型(整型 布尔型) 浮点型

python复合数据类型:元组、列表、字典、集合

数据类型之数字类型介绍

整数类型

python中的整型,即int类型,Python中没有对整型数字大小限制;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 整数类型示例
x = 10
print(x) # 输出x的值
print(type(x)) #打印类型,type()函数用于输出变量的类型
# 将不同进制数转成十进制
print(0x11, 0b101, 0O12, 20)
#为实现进制数互相转换,Python中内置了用于转换的函数:
y = 0b10001
print(bin(y),oct(y),int(y),hex(y))

#运行结果
10
<class 'int'>
17 5 10 20
0b10001 0o21 17 0x11

浮点类型

在python中小数都属于浮点型(float),有两种表现形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 小数点形式(常用),较小的小数表示
f = 3.14
num1 = 3.1415926 + 3.1415926
x = 1
y = "Corazon"
f1 = -3.14E2 # 指数形式: aEn 或 aen,较大的小数表示
f2 = 3.14e-2 # 指数形式: aEn 或 aen,较大的小数表示
print("f:",type(f))
print(num1)
print(3.1415926+3.1415926)
print("x:",type(x), "y:",type(y))
print("f1:",type(f1),"f2:",type(f2))

# 执行结果
f: <class 'float'>
6.2831852
6.2831852
x: <class 'int'> y: <class 'str'>
f1: <class 'float'> f2: <class 'float'>

布尔类型

布尔型(Bool)是一种特殊数据类型,常用于判断,这种类型只有两种值,即"真"与"假"。

1
2
3
4
5
6
7
8
print(4 == 2,5 > 1)
# 也可以做字符判断 --判断大小 依据ascii编码
name = "zhangsan"
print(name == "lisi")

# 打印结果
False True
False
1
2
3
4
# 不光上面代码语句的结果是布尔值,单独一个数据没有进行计算也可以都有自己的布尔值,这就涉及到布尔的零值。
# 任意数据类型都有一个具体值的布尔值为False,我们称为零值。该类型的其他值的布尔值皆为True。
print(bool("Cozrzon"),bool(0)) # 字符串的零值True False
print(bool(24),bool(0)) # 整型的零值 True False

数据类型间相互转换方法

python内置了进行转换数据类型的函数,常见有int()、float(),示例如下:

1
2
3
4
5
6
7
8
9
10
11
# int() 转成整型
# float() 转成小数
x = 3
y = 3.14
#注意:浮点型转换为整数型时直接舍去小数部分(向下取整)
print(x, type(x), y, type(y))
print(float(x), type(float(x)), int(y), type(int(y)))

# 运行结果
3 <class 'int'> 3.14 <class 'float'>
3.0 <class 'float'> 3 <class 'int'>

数据类型值字符类型介绍

字符串格式

单行字符串:

1
2
3
4
5
6
# 用双引号,直接输出字符串
print("hi,Corazon")

# 以变量的形式输出字符串,采用单引号定义
s1 = 'hi,Corazon'
print(s1)

多行字符串也叫文本字符串,就是三个单引号或者三个双引号圈住的内容,实际上也是字符串;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
s = """
s1 = "hi,boy\nhi,girl"
s2 = 'I\'m Corazon'
s3 = "D:\\中科人才\\python.exe"
s4 = "我是中科人才,\
我喜欢python"
长字符串中放置单引号或者双引号不会导致解析错误
"""
print(s)

# 打印结果
s1 = "hi,boy
hi,girl"
s2 = 'I'm Corazon'
s3 = "D:\中科人才\python.exe"
s4 = "我是中科人才,我喜欢python"
长字符串中放置单引号或者双引号不会导致解析错误

字符串信息转义设置

有些特殊字符信息前面加\ 转义字符会有特殊的含义作用:

转义字符说明转义字符说明
\n换行符,将光标位置移到下一行开头\r回车符,将光标位置移到本行开头
\t水平制表符,也即 Tab 键,一般相当于四个空格\b退格(Backspace),将光标位置移到前一列
\任意字符转义,例如'",\行尾\不换行,多行编辑一行输出

字符串内置方法

在对字符串进行操作时,还会存在一些内置的方法函数,完成对字符串信息的特殊需求处理:

方法作用示例输出
upper大写"hello".upper()"HELLO"
lower小写"Hello".lower()"hello"
startswith()是否以a开头"Corazon".startswith("a")True
endswith()是否以a结尾"Corazon".endswith("a")False
isdigit()是否全数字'123'.isdigit()True
isalpha()是否全字母'Corazon123'.isalpha()False
isalnum()是否全为字母或数字'Corazon123'.isalnum()True
strip()去两边空格" hi Corazon \n".strip()"hi Corazon"
join()多字符串连接"-".join(["Corazon","eric"])"Corazon-eric"
split()分割字符串,默认空格"Corazon-eric".split("-")['Corazon', 'eric']
find()返回指定字符串索引,没有返回-1"world".find("w")0
index()返回指定字符串索引,找不到会报错"world".index("w")0
count()统计指定字符串出现次数"world".count("l")1
len(s)返回字符串长度len("Hello,Corazon!!!"))16
replace()替换old为new'oldold'.replace('old','new',1)
‘oldold’.replace(‘old’,‘new’)
newold
newnew
format()格式化方法

注意:index()和find()方法只能匹配首个指定字符的索引

复合数据类型

元组数据类型

元组数据类型定义:

元组的元素只能读,不能进行修改(下标不能改 元素不能改 长度不能增加 但整体可以改),通常情况下,元组用于保存无需修改的内容;元组使用小括号表示声明(定义)一个元素数据类型:

1
(element1, element2, element3, ..., elementn)

注意:当创建的元组中只有一个字符串类型的元素时,该元素后面必须要加一个逗号,否则python解释器会将它视为字符串

02 元组数据序列操作:

元组数据信息调取和列表操作基本一致,支持索引和切片操作。

列表数据类型

列表会将所有元素都放在一对中括号[]里面,相邻元素之间用逗号分隔,具体表现形式:

1
[element1, element2, element3, ..., elementn]

注意:不同于C,java等语言中的数组,python的列表可以存放不同的任意数据类型对象。

1
2
3
4
5
6
7
8
9
l = [123,"zkrc",True]
print(l,type(l),len(l))
for item in l:
print(item,type(item))
# 执行结果
[123, 'zkrc', True] <class 'list'> 3
123 <class 'int'>
zkrc <class 'str'>
True <class 'bool'>
1
2
3
4
5
# 列表方式赋值变量 --列表值与变量数量要一一对应
a,b = [1,2]
print(a,b)
a,b = [input("请输入第一个字符: "),input("请输入第二个字符: ")]
print(a,b)

列表数据信息调取

我们可以使用索引(index)访问列表中的某个元素,也可以使用切片操作访问列表中的一组元素值信息,从而得到的是一个新的子列表。

1
2
3
4
5
6
7
8
9
索引求值
l = [10,11,12,13,14]
print(l[2]) # 12
print(l[-1]) # 14

切片操作
l = [10,11,12,13,14]
print(l[2:5]) #[12, 13, 14]
print(l[-3:-1]) #[12, 13]

列表内置方法

方法作用示例结果
append()向列表追加元素l.append(4)l``:[1, 2, 3, 4]
insert()向列表任意位置添加元素l.insert(0,100)l``:[100, 1, 2, 3]
extend(``)向列表合并一个列表l.extend([4,5,6])l``:[1, 2, 3, 4, 5, 6]
pop()根据索引删除列表元素l.pop(1)l``:[1, 3]
remove()根据元素值删除列表元素l.remove(1)l``:[2, 3]
clear()清空列表元素l.clear()l``:[]
sort()排序(升序)l.sort()l``:[1,2,3]
reverse()翻转列表l.reverse()l``:[3,2,1]
count()元素重复的次数2是元素l.count(2)返回值:1
index()查找元素对应索引l.index(2)返回值:1

字典数据类型

字典是python提供的唯一内键的映射(mapping type)数据类型,python使用{ }创建字典。

由于字典中每个元素都包含键(key)和值(value)两部分,因此在创建字典时,键和值之间使用英文冒号:分隔。相邻元素之间使用英文逗号,分隔,所有元素放在大括号 { } 中,字典的元素也叫成员,是一个键值对。

1
dictname = {'key1':'value1', 'key2':'value2', ...}

同一字典中的各个键必须唯一,不能重复。

字典的键值对原本是无序的,但是在python3.6版本之后,字典默认做成有序的了。

字典内置的方法

方法作用示例结果
get()查询字典键值,取不到返回默认值d.get("name",None)"zkrc"
setdefault()查询字典某键的值,取不到给字典设置键值,同时返回设置的值d.setdefault("age",20)18
keys()查询字典中所有的键d.keys()['name','age']
values()查询字典中所有的值d.values()['zkrc', 18]
items()查询字典中所有的键和值d.items()[('name','zkrc'),`` ('age', 18)]
pop()删除字典指定的键值对d.pop(“age”){'name':'zkrc'}
popitem()删除字典最后的键值对d.popitem(){'name':'zkrc'}
clear()清空字典d.clear(){}
update()更新字典

集合数据类型

Python 中的集合,和数学中的集合概念一样,由不同可hash的不重复的元素组成的集合。

Python 集合会将所有元素放在一对大括号 {} 中,相邻元素之间用“,”分隔。

同一集合中,只能存储不可变的数据类型,包括整形、浮点型、字符串、元组,无法存储列表、字典、集合这些可变的数据类型,否则 Python 解释器会抛出 TypeError错误。

1
{element1,element2,...}

说明:由于集合中的元素是无序的,因此无法向列表那样使用下标访问元素,访问集合元素最常用的方法是使用循环结构;

集合内置方法

方法作用示例结果
add()向集合添加元素a.add(4){1, 2, 3, 4}
update()向集合更新一个集合a.update({3,4,5}){1, 3, 4, 5}
remove()删除集合中的元素a.remove(2){1, 3}
discard()删除集合中的元素a.discard(2){1, 3}
pop()删除集合第一个元素a.pop(){2,3}
clear()清空集合a.clear(){}
intersection()返回两个集合的交集a.intersection(b){3}
difference()返回两个集合的差集a.difference(b)
b.difference(a)
{1,2}
{4,5}
symmetric_difference()返回两个集合的对称差集a.symmetric_difference(b){1, 2, 4, 5}
union()返回两个集合的并集a.union(b){1, 2, 3, 4, 5}

运算符号介绍

数运算符说明

运算符说明实例结果
+1+12
-1-10
*1*33
/除法4/22
//整除7 // 23
%取余,求模,即返回除法的余数7 % 21
**幂运算/次方运算2 ** 416
|5|37
&5&31
^异或5^36

Tips:事实上,a | b=(1 & b)+(a ^ b)

位运算符说明

运算符说 明用法举例等价形式
=赋值x = yx = y
+=加赋值x += yx = x + y
-=减赋值x -= yx = x - y
*=乘赋值x *= yx = x * y
/=除赋值x /= yx = x / y
%=取余数赋值x %= yx = x % y
**=幂赋值x **= yx = x ** y
//=取整数赋值x //= yx = x // y
&=按位与赋值x &= yx = x & y
|=按位或赋值x |= yx = x | y
^=按位异或赋值x ^= yx = x ^ y
<<=左移赋值x «= yx = x << y, y 指左移位数
>>=右移赋值x »= yx = x >> y, y 指右移位数

比较运算符说明

比较运算符说明
>大于
<小于
==等于
>=大于等于(等价于数学中的 ≥)
<=小于等于(等价于数学中的 ≤)
!=不等于(等价于数学中的 ≠)
is判断两个变量所引用的对象是否相同
is not判断两个变量所引用的对象是否不相同

逻辑运算符说明

逻辑运算符含义基本格式说明
and与运算x and y当x和y都为真时结果才为真。
or或运算x or y当x和y都为假时结果才是假。
not非运算not y对x的结果取相反的结果。

成员运算符说明

in和not in用于测试给定数据是否存在于序列(如列表、字符串)中:

in作用是,如果指定字符在字符串中,则返回True,否则返回False。not in的作用刚好相反。

编写运算符应用示例代码:

1
2
3
4
5
6
7
x="zkrc"
y="b"
print(y in x)
print(y not in x)
# 运行结果
False
True

输入输出应用

输入输出函数说明

print()函数用于打印内容或变量等输出,是python中最最用的函数。

函数语法格式:

1
print(value1, ..., sep=' ', end='\n', file=sys.stdout,flush=False)

函数参数信息:

序号函数参数解释说明
01value打印的对象,之间用逗号分隔
02sep打印的两个值之间的分隔符,默认是空格
03end打印输出以什么结尾,默认是换行符\n
04file输出的文件对象,默认是sys.stdout,标准输出
05flush表示要强制冲洗流(忽略)

print() 函数使用以%开头的转换说明符对各种类型的数据进行格式化输出,具体请看下表:

符号类型示例
%s字符串"Hello %s" % "World"
%d整数"Age: %d" % 25
%f%F浮点数"Price: %.2f" % 99.87699.88
%x十六进制整数"Hex: %x" % 255ff
%%百分号本身"Discount: 10%%"

代码操作示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
name = "Corazon"
sex = "Male"
age = 24
print(name, sex, sep=":", end=" ")
print(age) # Corazon:Male 24 与上行合并为同一行
print("你的名字是:", name, "你的性别:", sex, "你的年龄", age) # 你的名字是: Corazon 你的性别: Male 你的年龄 24
# 解决空格问题
print("你的名字是:", name, " 你的性别:", sex, " 你的年龄", age, sep='') # 你的名字是:Corazon 你的性别:Male 你的年龄24
# 同时输出字符串和变量,用+拼接
info = "你的名字是:" + name
print(info) # 你的名字是:Corazon

##Print格式化输出
# 方法1:{0}、{1}、{2}分别表示j,i,j+i,单引号里面是输出格式。
print("你的名字是{0},你的性别:{1},你的年龄:{2}".format(name, sex, age)) # 你的名字是Corazon,你的性别:Male,你的年龄:24
# 方法2:类似于C语言格式输出,使用%开头格式输出
print("你的名字是%s,你的性别:%s,你的年龄:%s" % (name, sex, age)) # 你的名字是Corazon,你的性别:Male,你的年龄:24

input()函数

input函数是用来接收用户输入的数据,会返回一个字符串类型的数据。如果想要得到其他类型的数据进行强制类型转化。代码操作示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 允许用户在终端下输入自己的账号和密码
name = input("请输入您的姓名:")
year = int(input("请输入您的出生年:"))
month = int(input("请输入您的出生月:"))
day = int(input("请输入您的出生日:"))
# 前面双引号内容是格式化字符串,%s就是占位符,占据一个位置,类似教室占座。
# 占位符%s最终会被后面的变量的值所替代。
# 中间的`%`是一个分隔符。
# 多个变量表达式必须使用小括号扩起来。
# %02d 以整数输出,如果不足2位整数的,左边加0补充进去
print("您好%s,您的出生日期为:%d-%02d-%02d" % (name,year, month, day))
# 执行结果
请输入您的姓名:Corazon
请输入您的出生年:2000
请输入您的出生月:6
请输入您的出生日:8
您好Corazon,您的出生日期为:2000-06-08

格式化输出

话不多说

% 格式化(传统方法)

1
2
3
name = "Alice"
age = 30
print("Name: %s, Age: %d" % (name, age)) # Name: Alice, Age: 30

高级控制:

1
2
3
4
5
6
7
8
# 宽度与对齐
print("[%10s]" % "left") # 右对齐:[ left]
print("[%-10s]" % "right") # 左对齐:[right ]

# 浮点数精度
print("π: %.03f" % 3.14159) # π: 3.142
print("a: %010.03f" % 1.23456) # a: 000001.235
print("a: %.010f" % 1.23456) # a: 1.2345600000

str.format() 方法

Python 2.6+版本支持str.format()` 方法:

1
2
3
print("Name: {0}, Age: {1}".format("Bob", 40))
print("Name: {name}, Age: {age}".format(name="Bob", age=40))
num=input("你还有{0}次机会,\n请输入一个1到20的整数:".format(5-count))

核心功能:

  • 位置参数
    "{0} + {1} = {2}".format(1, 2, 3)1 + 2 = 3

  • 关键字参数
    "User: {username}".format(username="admin")

  • 混合使用
    "{0} {last}".format("John", last="Doe")

格式化规范(: 后定义格式):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 数字格式化
print("π: {:.3f}".format(3.14159)) # π: 3.142
print("Hex: {:x}".format(255)) # ff

# 文本对齐
print("[{:>10}]".format("right")) # [ right]
print("[{:^10}]".format("center")) # [ center ]

# 符号显示
print("Balance: {:+d}".format(100)) # +100

# 千位分隔符
print("{:,}".format(1000000)) # 1,000,000

# 百分比
print("Ratio: {:.2%}".format(0.25)) # 25.00%

f-strings

Python 3.6+,推荐。在渗透测试Python脚本中经常使用f-strings方式构建PayLoad

1
2
3
name = "Corazon"
age = 35
print(f"Name: {name}, Age: {age}") # Name: Corazon, Age: 35

高级特性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 表达式计算
print(f"Sum: {5 + 3}") # Sum: 8

# 函数调用
print(f"Uppercase: {'hello'.upper()}") # Uppercase: HELLO

# 格式控制
pi = 3.14159
print(f"π: {pi:.3f}") # π: 3.142 与%格式一样
print(f"Hex: {255:x}, int: {0b11111111:d}, Oct: {255:o}, Bin: {255:b}") # Hex: ff, int: 255, Oct: 377, Bin: 11111111

# 对齐与填充(字符串后接':')
print(f"[{'left':<10}]") # [left ]
print(f"[{'right':>10}]") # [ right]
print(f"[{'center':^10}]") # [ center ]
print(f"[{'pad':*>10}]") # [*******pad]
# 构建cookie SQL注入字典,爆破某一用户密码(部分):
cookies = {'TrackingId': f"{Tracking_id}' and ascii(substr((select password from {tablename} where username='{username}'),{password_index},1)) > {ascii_mid}--+;"}

# 日期格式化
from datetime import datetime
now = datetime.now()
print(now) # 2025-07-16 14:16:57.921635
print(f"Now: {now:%Y-%m-%d}") # Now: 2025-07-16

# 原始字符串(避免转义)
name = "Corazon"
print(fr"Raw: \n {name}") # Raw: \n Corazon
print(f"Raw: \\n {name}") # Raw: \n Corazon

模板字符串(string.Template

string.Template 是 Python 标准库中提供的一种安全、简单的字符串替换机制,特别适合处理用户提供的模板或需要防止注入攻击的场景。

基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from string import Template

#01 创建模板对象
t = Template("Hello, $name! Today is $day.")

# 使用 substitute() 方法进行安全替换:
result = t.substitute(name="Alice", day="Monday")
print(result) # 输出: Hello, Alice! Today is Monday.

# 使用 safe_substitute() 方法,当缺少变量时不会报错:
result = t.safe_substitute(name="Bob")
print(result) # 输出: Hello, Bob! Today is $day.


#02 变量表示形式
from string import Template

# 简单变量 ($var)
t = Template("Welcome, $user!")
print(t.substitute(user="Admin")) # Welcome, Admin!

# 包裹变量 (${var})
# 当变量名后需要紧跟字母、数字或下划线时使用,避免歧义:
t = Template("Total: ${amount}USD")
print(t.substitute(amount=100)) # Total: 100USD


#03 使用字典进行替换
data = {"name": "Corazon", "item": "book", "price": 29.99}
t = Template("$name bought a $item for $$$price")
print(t.substitute(data)) # Corazon bought a book for $29.99


#04 特殊字符处理
# 转义 `$` 符号,使用两个 `$` 表示字面值的美元符号:
t = Template("Cost: $$ $amount")
print(t.substitute(amount=50)) # Cost: $ 50

# 处理包含 `$` 的值
t = Template("Value: $val")
print(t.substitute(val="$100")) # Value: $100
高级用法
1
2
3
4
5
6
7
8
9
10
11
12
# 2.自定义分隔符(继承 Template)
class MyTemplate(Template):
delimiter = '#' # 将分隔符改为 #
idpattern = r'[a-z]+' # 只允许小写字母变量名
t = MyTemplate("Hello, #name! Your code is #code")
print(t.substitute(name="Corazon", code="XYZ123")) # Hello, Corazon! Your code is XYZ123

# 3.处理无效标识符
class SafeTemplate(Template):
idpattern = r'[_a-z][_a-z0-9]*' # 标准标识符规则
t = SafeTemplate("$user_name: $score")
print(t.substitute(user_name="Eve", score=95)) # Eve: 95
安全特性

string.Template 的主要安全优势:

  1. 不执行表达式:不会像 f-strings 那样执行任意代码

  2. 无格式化功能:不能访问对象属性或执行方法

  3. 简单替换:只进行直接的字符串替换

1
2
3
4
# 安全示例 - 防止注入攻击
user_input = "${os.system('rm -rf /')}" # 恶意输入
t = Template("User data: $data")
print(t.safe_substitute(data=user_input)) # 安全输出: User data: ${os.system('rm -rf /')}
实际应用场景
  1. 邮件模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
email_template = Template("""
Dear $name,

Your order #$order_id has been shipped.
Tracking number: $tracking_num

Regards,
$company
""")

data = {
"name": "Alice",
"order_id": "12345",
"tracking_num": "ZYX987",
"company": "ACME Corp"
}

print(email_template.substitute(data))

2. 配置文件模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
config_template = Template("""
[DATABASE]
host = $db_host
port = $db_port
user = $db_user
password = $db_pass
""")

db_config = {
"db_host": "localhost",
"db_port": 5432,
"db_user": "admin",
"db_pass": "secure123"
}

print(config_template.substitute(db_config))

3. 多语言支持

1
2
3
4
5
6
7
8
9
10
templates = {
"en": Template("Hello, $name!"),
"es": Template("¡Hola, $name!"),
"fr": Template("Bonjour, $name!")
}

def greet(name, lang="en"):
return templates[lang].substitute(name=name)

print(greet("Pierre", "fr")) # Bonjour, Pierre!

其他方法

(1) 字符串拼接

1
print("Name: " + name + ", Age: " + str(age))

(2) str.join() 处理列表

1
2
words = ["Python", "is", "powerful"]
print(" ".join(words)) # Python is powerful

总结对比

方法易读性灵活性安全性版本要求
% 格式化所有版本
str.format()Python 2.6+
f-strings极高极高Python 3.6+
string.Template所有版本

流程控制语句

python流程控制语句介绍

软件程序是由语句构成,而流程控制语句是用来控制程序中每条语句执行顺序的语句;可以通过控制语句实现更丰富的逻辑以及更强大的功能;几乎所有编程语言都有流程控制语句,功能也都基本相似,其流程控制方式有:

  • 顺序结构

  • 分支结构

  • 循环结构

最简单最常用的就是顺序结构,即语句从上至下逐一执行:

1
2
print("I am zkrc.")
print("I like python.") # 从上到下依次执行

流程控制分支语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 单分支语句语法结构:
if 表达式:
代码块

# 双分支语句语法结构:
if 表达式:
代码块1
else:
代码块2

# if 表达式1:
代码块1
elif 表达式2:
代码块2
...更多elif语句
else
代码块 n

双分支语句中的pass用法:

  • 空语句,不做任何事务处理,一般用作占位

  • 保证格式完整

  • 保证语义完整

一些高阶用法:

1
2
3
#01 打印num1和num2中较大的数
num1, num2 = 1, 2
print(num1 if num1 > num2 else num2) # 2

流程控制循环语句

Python语言中的循环语句支持 while循环(条件循环)和for循环(遍历循环)

流程控制循环语句-while

循环语句语法格式:

1
2
while 表达式:
循环体

流程控制循环语句-for

循环语句语法格式:

1
2
for 迭代变量 in 字符串|列表|元组|字典|集合:
代码块

流程控制循环嵌套

1
2
3
4
5
6
7
8
9
10
#01 独立嵌套
for i in range(5): #5次
for j in range(5): #5次
print(" *",end="")
print("")
#02 关联嵌套
for i in range(1,5): #控制行数
for j in range(i): #控制每行个数
print(" *",end="")
print("")

循环控制语句说明

如果在某一时刻(在不满足结束条件的情况下)想提前结束循环,可以使用break或continue关键字;

循环控制语句-break

当break关键字用于for循环时,会终止循环而执行整个循环语句后面的代码信息;break 退出的是循环 exit() 或者quit() 退出的是脚本

1
2
3
4
5
for i in range(1,6):
if i == 3:
break
print(i)
print("end")

循环控制语句-continue

不同于break退出整个循环,continue指的退出当次循环,但会继续在循环结构中,完成后续的循环操作;

1
2
3
4
5
for i in range(1,6):
if i == 3:
continue
print(i)
print("end")

编程函数

函数定义语法格式:

1
2
def 函数名(var1,var2...varn):
操作指令信息

本文参考:

shell编程

这里说的Shell 脚本(shell script),是在Linux 环境下运行的脚本程序

Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)

  • Bourne Again Shell(/bin/bash)

  • C Shell(/usr/bin/csh)

  • K Shell(/usr/bin/ksh)

  • Shell for Root(/sbin/sh)

  • ……

Bash是大多数Linux 系统默认的 Shell,本文也仅关注Bash Shell。

在一般情况下,并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash

#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

阅读全文 »

雷神众测 需要技术 有基础再参加 不然号废了 钱少通过率可以
360众测 要先打靶场 钱多 通过率低 重复率高 不推荐漏洞盒子 需要积分补天
EDU众测 钱很少 不难火线众测 银行众测 快凉了

众测思路看手速 收录范围广

众测厂商等级银行证券:难政府、EDU、企业:中等私人项目:简单(捡钱,认识项目经理)

fofa、hunter到处资产 扫指纹 定位oa和框架 扫nday
arl边跑边测,怼着后台和功能

思路(不太常规,别人不太会用)利用icon收集信息查找网站的真是ip 挖网站的c端(比较容易歪) 不确定可以问问利用站点标题进行模糊搜索公众号小程序 关键词搜索谷歌/bing语法:很多玉米螟需要正确路径才能打开,不然40X

漏洞挖掘
nday 扫框架 组件漏洞未授权 弱口令逻辑漏洞短信轰炸(看能不能并发)

本文参考:

文件系统介绍

根目录结构及其功能

系统目录结构:

目录内容
bin目录全称(binary) 存放二进制命令文件(普通用户可以使用)
sbin目录存放二进制命令文件(root用户可以使用)
etc目录存放软件程序或系统程序配置文件
lib目录会存放需要调取库文件信息 旧软件程序调取库文件
lib64目录会存放需要调取库文件信息 新软件程序调取库文件
media可以存放实例视频或图片 可以用于作为默认挂载点
mnt可以用于作为默认挂载点
opt目录存放第三方软件程序数据 等价于Windows program files
usr目录存放第三方软件程序数据 等价于Windows program files
root用户信息存放家目录 root用户的家 ~
home用户信息存放家目录 普通用户的家~
boot目录存放系统启动相关的数据
dev目录会存放一些设备文件信息
var目录全称(variable),用于存放日志文件的
tmp目录用于临时存放文件信息 类似于Windows 回收站
proc由内核组成,目录中会存放系统内核配置信息或服务进程信息,不会占用磁盘空间,只会占用内存空间

系统配置信息

文件路径
网卡配置(centos)/etc/sysconfig/network-scripts/ifcfg-ens33
/etc/sysconfig/network-scripts/ifcfg-eth0
网卡配置(kali)/etc/systemd/networkd.conf
主机名/etc/hostname
域名配置文件/etc/resolv.conf
环境变量/etc/profile
/etc/bashrc
~/.bash_profile
~/.bashrc
开机自动加载命令文件/etc/rc.d/rc.local
用户登录信息提示文件/etc/motd
系统版本信息/etc/[redhat/centos/os(kali是os)]-release
用户相关文件信息/etc/passwd
cpu相关信息,包括型号、主频、内核信息等/proc/cpuinfo
操作系统版本信息/proc/version
系统全局 cron 配置文件/etc/crontab
docker配置文件
nginx配置文件
nginx启动文件
配置函数信息的文件/etc/init.d/functions
/etc/docker/daemon.json
docker代理配置文件/etc/systemd/system/docker.service.d/http-proxy.conf
目录路径
自动加载运行脚本目录/etc/profile.d/
系统安装软件目录(rpm 手动方式 yum 自动方式)
存放独立 cron 配置文件的目录/etc/cron.d/
每个用户的 cron 表存储目录/var/spool/cron/

日志信息

Linux系统拥有非常灵活和强大的日志功能,可以保存几乎所有的操作记录,并可以从中检索出我们 需要的信息。

  1. 内核及系统日志由系统服务rsyslog统一进行管理,日志格式基本相似

  2. 用户日志记录系统用户登录及退出系统的相关信息

  3. 程序日志由相应的应用程序进行独立管理。如:web服务,ftp服务 常见日志文件

日志文件作用
/var/log/secure登录日志。记录验证和授权方面的信息,只要涉及账号和密码的程序都会记录, 比如 SSH登录, su登录,切换用户, sudo授权,甚至添加用户和修 改用户密码都会记录在这 个日志文件中。新版的ubuntu、debian、kali已经没有这个文件了 , 换成了 /var/log/auth.log
/var/log/message通用的系统活动日志。记录内核消息、系统服务(邮件、cron等)的常规信息、非关键网络错误等。
/var/log/cron每当cron进程开始一个工作时,就 会将相关信息记录在这个 文件中。
/var/log/syslog所有系统活动信息(比 messages 更全面)。包含内核、服务、应用等除认证外的所有信息。
/var/log/wtmp永久记录所有用户的登录、注销信息,同时记录系统的启动、重启、 关机事件。同样这个文件也是一个二进制文件,不能直接编辑查看, 而需要使用 last命令来查看
/var/run/utmp记录当前已经登录的用户信息,这个文件会随着用户的登录和注销不 断变化,只记录当前登录用户的信息。同样这个文件不能直接编辑查 看,而要使用 w,who,users等命令来查询
/var/log/btmp记录所有失败登录日志信息。这个文件是二进制文件,不能直接编辑 查看,使用 lastb命令或 last -f /var/log/btmp 命令可以查看btmp文件。
/var/log/cups涉及所有打印信息的日志。
/var/log/faillog包含用户登录失败信息。此外,错误登录命令也会记录在本文件中
/var/log/messages记录系统重要信息的日志。这个日志文件中会记录Linux系统的绝大 多数重要信息,如果系统出现问题时,首先要检查的就应该是这个日 志文件。此外, mail,cron,daemon,kern和auth等内容也记录在var/log/messages
/var/log/dmesg包含内核缓冲信息( kernel ring buffer)。在系统启动时,会在屏幕上显示许多与硬件有关的信息。可以用 dmesg命令直接查看内核自检信息
/var/log/auth.log包含系统授权信息,包括用户登录和使用的权限机制等。
/var/log/boot.log包含系统启动时的日志。
/var/log/daemon.log包含各种系统后台守护进程日志信息。
/var/log/dpkg.log包括安装或 dpkg命令清除软件包的日志。
/var/log/kern.log包含内核产生的日志,有助于在定制内核时解决问题。
/var/log/lastlog记录系统中所有用户最后一次登录时间的日志,这个文件是二进制文 件,不能直接编辑查看,而要使用 lastlog命令查看
/var/log/user.log记录所有等级用户信息的日志。
/var/log/alternatives.log更新替代信息都记录在这个文件中。
/var/log/anaconda.log在安装Linux时,所有安装信息都储存在这个文件中。
/var/log/yum.log包含使用 yum安装的软件包信息。
/var/log/maillog
/var/log/mail.log
包含系统运行电子邮件服务器的日志信息。例如, sendmail日志信息就全部送到这个 文件中

比较重要的几个日志:

登录失败记录:/var/log/btmp #lastb
最后一次登录:/var/log/lastlog #lastlog
登录成功记录: /var/log/wtmp #last
登录日志记录:/var/log/secure
目前登录用户信息:/var/run/utmp #w、who、users
历史命令记录:history
仅清理当前用户:history -c

网卡配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
vim  /etc/sysconfig/network-scripts/ifcfg-ens33
# 网络接口类型(通常为 Ethernet 或 Bridge)
TYPE=Ethernet
# 代理配置方式(none 表示不使用代理)
PROXY_METHOD=none
# 是否仅用于浏览器代理(no 表示不限制)
BROWSER_ONLY=no
# 获取IP地址的方式(static 表示静态IP,dhcp 表示动态获取)
BOOTPROTO=static
# 静态IP地址(需根据实际网络规划设置)
IPADDR=10.0.0.5
# 子网掩码(定义IP地址的网络部分)
NETMASK=255.255.255.0
# 默认网关(路由器的IP地址)
GATEWAY=10.0.0.254
# 主DNS服务器地址(注意:此处错误添加了域名,应仅保留IP)
DNS1=10.0.0.254
# 是否启用默认路由(yes 启用)
DEFROUTE=yes
# IPv4配置失败时是否视为严重错误(no 表示不终止网络服务)
IPV4_FAILURE_FATAL=no
# 是否初始化IPv6(yes 启用)
IPV6INIT=yes
# 是否自动配置IPv6地址(yes 启用)
IPV6_AUTOCONF=yes
# 是否启用IPv6默认路由(yes 启用)
IPV6_DEFROUTE=yes
# IPv6配置失败时是否视为严重错误(no 表示不终止网络服务)
IPV6_FAILURE_FATAL=no
# IPv6地址生成模式(增强隐私保护)
IPV6_ADDR_GEN_MODE=stable-privacy
# 网络连接名称(自定义标识)
NAME=ens33
# 设备唯一标识符(系统自动生成,通常无需修改)
UUID=27a73818-89f3-4991-9890-2da7924a73c4
# 物理设备名称(需与网卡实际名称一致)
DEVICE=ens33
# 是否在系统启动时激活此连接(yes 启用)
ONBOOT=yes

更改配置需要重启网卡systemctl restart networkservice network restart

域名解析配置

1
2
3
vim /etc/resolv.conf    #域名解析配置文件
nameserver 10.0.0.254 #DNS服务器,不能写错 写错就访问不了了
cat /cat /etc/hosts #访问内网的域名配置文件

系统管理

环境变量

和变量 环境变量 别名相关的配置文件信息:/etc/profile/etc/bashrc~/.bash_profile~/.bashrc/etc/profile.d/

网安关注应急效应,异常占用资源、进程关闭后再次运行,有可能是 profile 被植入脚本运行命令。/etc/profile/etc/bashrc、两个文件写到任意一个都会受到影响(把某个恶意跑进程的脚本放进去)。局部变量优于全局变量

如果想让变量重启后仍然有效就修改这些文件。

其他

文件时间信息分类

文件时间信息分类英文全称缩写触发条件
文件修改时间modified timemtime文件信息内容发生变动时,会修改调整此时间信息
文件访问时间access timeatime文件信息内容被访问读取时,会修改调整此时间信息
文件改变时间change timectime文件属性信息发生变动时,会修改调整此时间信息

inode与block

文件索引-inode 数据信息索引 每创建一个文件可用的索引次数就会减少

文件大小-block 数据信息容量 文件中的信息内容不断添加,数据块就会不断减少

查看相关信息:

df -i --inode 可用数为0 表示磁盘空间不足

df block 可用数 为0 表示磁盘空间不足

inode:默认大小为128或者256字节

block:默认大小1-4kb

由于磁盘分区都比较大,所以一个磁盘中会创建出大量的inode和block

本质上有数字编号和实际存储空间对应 便于检索数据信息 —指针 库管 会议 仓库提货过程

存储的数据文件中包含数据文件属性

描述数据的数据 – 元数据

系统进程

程序(Program)是经开发编译后形成的静态可执行代码集合,是数据与指令的有序封装(如磁盘中存储的wechat.exenginx二进制文件),其生命周期独立于运行状态,可长期保存在存储介质中。

当程序被加载到内存并开始执行时,便转化为进程(Process)—— 它是程序的动态运行实例。此时,操作系统会为其分配专属的系统资源(如内存空间、CPU 时间片、文件描述符等),并记录其运行状态(如就绪、运行、阻塞等)。同时,进程会关联明确的所属用户,受系统权限管控。

简言之,程序是 “静态的代码文件”,而进程是 “动态的执行过程”。例如,双击wechat.exe后,操作系统将其加载到内存并启动执行,此时任务管理器中显示的 “微信” 进程,便是该程序的运行实例。

进程与程序的本质区别

维度程序(Program)进程(Process)
存在形态静态:以二进制文件、脚本等形式存储于磁盘动态:加载到内存中执行的指令流与数据集合
资源关联不占用系统运行时资源(仅占用存储资源)占用 CPU、内存、I/O 等实时系统资源
生命周期长期存在(除非主动删除文件)随执行开始而创建,随任务完成或异常终止而消亡(有明确生命周期)
核心属性仅包含代码逻辑与静态数据包含运行状态、资源句柄、进程 ID(PID)、所属用户等动态元信息

理解进程与程序的区别,是系统运维的基础:程序是 “待执行的蓝图”,而进程是 “正在施工的现场”—— 运维的核心工作,正是通过监控、管理这些 “现场”,确保系统按预期稳定运行。

根据进程生命周期,存在两种特殊进程情况:

  • 僵尸进程:

异常进程 任务没处理完子进程崩溃了,就会出现僵尸进程(Z) 儿子死了父亲还在 关注 木马病毒 产生大量Z 会占用大量内存资源

  • 孤儿进程:

异常进程 任务处理完毕告知父进程时,父进程异常了,产生孤儿进程,系统会自动回收孤儿进程 了解

查看当前静态进程情况

ps -ef|ps aux

1
2
ps aux   #USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND
ps -ef #UID, PID, PPID, C, STIME, TTY, TIME, CMD

以下是 ps auxps -ef 命令中所有列的英文缩写及含义对照表:

英文缩写含义说明出现命令
USER进程所属的用户名(用户标识,字符串形式)ps aux
PIDProcess ID,进程唯一标识符(进程 ID)ps aux、ps -ef
%CPU进程占用的 CPU 资源百分比(单位:%)ps aux
%MEM进程占用的物理内存百分比(单位:%)ps aux
VSZVirtual Set Size,虚拟内存大小(单位:KB,包含物理内存和交换空间等)ps aux
RSSResident Set Size,实际占用的物理内存大小(单位:KB,不包含交换空间)ps aux
TTY进程关联的终端设备(? 表示无终端关联,通常为后台进程)ps aux、ps -ef
STATProcess State,进程状态(如 R 运行、S 睡眠、Z 僵尸、T 停止等)ps aux
START进程启动的时间(格式随系统时间范围变化,如时分、月日等)ps aux
TIME进程累计占用的 CPU 时间(格式:时:分: 秒)ps aux、ps -ef
COMMAND启动进程的完整命令及参数ps aux
UIDUser ID,进程所属用户的 ID(用户标识,数字形式)ps -ef
PPIDParent Process ID,父进程的 ID(标识当前进程的父进程)ps -ef
CCPU 使用率(整数形式,反映进程近期的 CPU 占用情况,精度低于 % CPU)ps -ef
STIME进程启动的时间(格式更紧凑,通常为时分或月日,随系统时间范围变化)ps -ef
CMD启动进程的命令及参数(可能因长度限制被截断)ps -ef

查看当前动态进程情况

top 输出分为 系统全局状态区进程详情区,两者共同构成系统实时运行快照。

在 Linux 系统运维中,top 命令是实时监控进程资源与系统性能的核心工具。它通过动态刷新的界面,提供 CPU、内存、进程状态等关键指标,帮助管理员快速定位资源瓶颈与异常进程。

top与 ps 命令的核心差异:

工具特性适用场景
ps静态快照,捕获某一时刻的进程状态(如 ps -aux)。记录历史状态、排查进程启动参数。
top动态监控,实时刷新资源占用与进程行为(默认 3 秒 / 次)。实时性能分析、异常进程定位。
系统全局状态区

系统全局状态区为输出的上半部分,以典型输出为例:

1
2
3
4
5
top - 09:27:45 up 5 days,  7:45,  4 users,  load average: 0.00, 0.01, 0.05  
Tasks: 123 total, 1 running, 121 sleeping, 1 stopped, 0 zombie
%Cpu(s): 0.1 us, 0.0 sy, 0.0 ni, 99.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1863032 total, 1121288 free, 256980 used, 484764 buff/cache
KiB Swap: 1535996 total, 1535996 free, 0 used. 1408888 avail Mem
  1. 第一行(系统基础信息)

    • 09:27:45:当前系统时间。

    • up 5 days, 7:45:系统已连续运行 5 天 7 小时 45 分钟(未重启)。

    • 4 users:当前登录用户数(含本地终端与远程连接)。

    • load average: 0.00, 0.01, 0.05
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42

      :系统平均负载,分别对应过去 1 分钟、5 分钟、15 分钟的活跃进程数。

      - **关键逻辑**:负载值代表处于 **可运行状态(`R`)** 或 **不可中断休眠状态(`D`)** 的进程数平均值。
      - **健康指标**:若 1 分钟负载值超过 CPU 核心数(如 4 核 CPU 负载 >4),表明系统短期过载;若 15 分钟负载持续偏高,需排查长期资源瓶颈。

      2. **第二行(进程总数统计)**

      - `123 total`:系统总进程数。
      - `1 running`:处于 `R` 状态的进程数(正在占用或等待 CPU)。
      - `121 sleeping`:处于 `S`(可中断休眠)或 `D`(不可中断休眠)状态的进程数。
      - `1 stopped`:处于 `T`(停止)状态的进程数(如被 `Ctrl+z` 暂停的 `ping` 进程)。
      - `0 zombie`:僵尸进程(`Z` 状态)数量,若大于 0 需检查父进程是否未回收资源。

      3. **第三行(CPU 资源占用)**

      - **`us`:用户态进程占用 CPU 的百分比(如应用程序)**。
      - `sy`:内核态进程占用 CPU 的百分比(如系统调用、进程调度)。
      - `ni`:调整过优先级(`nice` 值非 0)的用户态进程占用 CPU 的百分比。
      - `id`:CPU 空闲百分比(数值越高,系统越空闲)。
      - **`wa`:CPU 等待 I/O 操作(如磁盘读写)的百分比,若长期高于 5% 需排查存储性能。**
      - `hi`:硬中断(如硬件设备触发的中断)占用 CPU 的百分比。
      - `si`:软中断(如内核定时器、网络数据包处理)占用 CPU 的百分比。
      - `st`:虚拟化环境中,物理 CPU 被其他虚拟机占用的百分比(`st` 过高可能意味着宿主机资源竞争)。

      4. **第四、五行(内存与交换分区)**

      - `KiB Mem`(物理内存):
      - `total`:总容量;`free`:完全空闲内存;`used`:进程直接占用内存;`buff/cache`:磁盘缓存(可释放供其他进程使用)。
      - `KiB Swap`(虚拟内存):
      - `avail Mem`:新进程可使用的总内存(含 `free` 及可释放的 `buff/cache`)。


      ##### 进程详情区(下半部分)

      以典型输出为例:

      ```bash
      PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
      53720 root 20 0 0 0 0 S 0.3 0.0 0:18.08 kworker/1:1
      1 root 20 0 202396 7300 4184 S 0.0 0.4 5:01.00 systemd
      2 root 20 0 0 0 0 S 0.0 0.0 0:00.93 kthreadd

字段说明:

字段含义说明
PID进程唯一标识,操作进程的核心索引(如 kill 53720)。
USER进程所属用户,用于权限追溯(如 root 进程通常拥有更高权限)。
PR进程调度优先级(范围 0-39,值越低优先级越高,内核动态调整)。
NInice 值(优先级偏移量,范围 -20~19,值越低优先级越高,用户可通过 nice 命令调整)14。
VIRT进程占用的虚拟内存总量(包括物理内存、交换分区、未使用的分配内存),类似 “建筑面积”。
RES进程实际使用的物理内存(不包括交换分区),类似 “实际使用面积”。
SHR进程共享的内存量(如动态链接库),类似 “公摊面积”。
S进程状态(R 运行、S 休眠、T 停止、Z 僵尸等)。
%CPU进程占用 CPU 的百分比(过去 3 秒内的平均值)。
%MEM进程占用物理内存的百分比(相对于总物理内存)。
TIME+进程累计占用的 CPU 时间(精确到 0.01 秒)。
COMMAND启动进程的命令(含参数时会截断显示,按 c 可显示完整路径)。
核心功能与快捷键

top 命令以交互式界面实时展示系统状态,支持以下核心操作:

  1. 基础交互

    • h?:调出帮助文档,查看所有快捷键与功能说明。
    • q:退出监控界面。
    • sd:调整刷新间隔(单位:秒),默认 3 秒刷新一次。
  2. 资源排序

    • P:按 CPU 使用率(%CPU)降序排序,快速定位高负载进程。
    • M:按内存使用率(%MEM)降序排序,排查内存占用异常。
    • T:按累计 CPU 时间(TIME+)排序,识别长期占用资源的进程。
  3. 视图优化

    • 1:展开多核 CPU 视图,显示每个物理核心的负载详情(如 %Cpu0%Cpu1)。
    • z:启用颜色高亮,区分不同数据区域(如红色标记高负载进程)。
    • b:高亮显示处于 R(运行)状态的进程,直观识别活跃任务。
  4. 高级控制

    • k:终止进程(输入 PID 后可指定信号,如 9 强制终止)。
    • r:调整进程优先级(通过 nice 值,范围 -20~19,值越小优先级越高)。
    • c:切换显示进程完整命令行(含参数),避免因名称截断导致的误判。
关键指标与异常排查
  1. 性能瓶颈定位

    • CPU 过载:若 %CPU 长期高于 80%,按 P 排序找出高负载进程,结合 ps -fp <PID> 分析代码逻辑或考虑扩容。
    • 内存泄漏:若 %MEM 持续增长且 avail Mem 下降,按 M 排序排查异常进程,使用 pmapvalgrind 分析内存分配。
    • 磁盘 I/O 瓶颈:若 wa 长期高于 10%,使用 iotop 定位高 I/O 进程,优化存储或升级硬件。
  2. 进程状态异常

    • 僵尸进程(Z 状态):终止父进程(kill <PPID>)或修复程序逻辑(确保调用 wait() 回收子进程资源)。
    • 不可中断进程(D 状态):可能因磁盘 I/O 阻塞,使用 strace 跟踪系统调用或检查存储设备健康状态。
  3. 虚拟化环境监控

    • st 持续高于 10%,表明宿主机资源不足,需迁移虚拟机或增加物理 CPU 核心。
数据保存与高级用法
  1. 批处理模式记录日志

    1
    top -b -n 5 > /tmp/top_monitor.log  # 记录 5 次刷新结果到文件  
    • -b:以批处理模式运行,适合脚本调用或离线分析。

    • -n 5:指定刷新次数,避免无限输出。

  2. 自定义显示字段

    • f 进入字段选择界面,通过方向键添加 / 删除字段(如 CODE 代码内存、DATA 数据段内存)。
    • o 调整字段顺序(如将 %CPU 列移至首位)。
  3. 多进程监控

    1
    top -p 1234,5678  # 同时监控多个进程(PID 1234 和 5678)  

进程状态(STAT)信息

在 Linux 系统中,通过pstop等命令查看进程时,状态标识(如RSZ等)直观反映了进程的当前行为。以下是各状态及相关符号的说明:

核心状态标识

进程状态由内核根据其资源占用、调度情况动态标记,核心状态标识(Process State Codes)如下:

  1. R(Running / Runnable,运行状态)
    进程处于 “可被 CPU 调度” 的状态:要么正在占用 CPU 执行指令,要么已就绪(等待 CPU 分配时间片)。此时进程位于内核的 “就绪队列” 中,是系统中 “活跃” 的典型代表。

  2. S(Interruptible Sleep,可中断休眠状态)
    进程因等待某事件(如 I/O 操作完成、信号触发、定时器超时等)而暂停执行,此时不占用 CPU 资源。该状态可被外部信号(如SIGINT)中断并唤醒(例如通过kill命令发送信号)。

    状态衍生符号(优先级相关):

    • S<:表示进程处于高优先级可中断休眠状态(优先级高于默认值),内核会优先调度其唤醒。

    • SN:表示进程处于低优先级可中断休眠状态(优先级低于默认值),调度优先级较低。

  3. T(Stopped / Traced,停止 / 跟踪状态)
    进程被主动暂停执行,通常由以下场景触发:

    • 收到暂停信号(如SIGSTOP),例如通过Ctrl+z暂停前台进程(如ping 223.5.5.5执行时,Ctrl+z会将其暂停为T状态);
    • 被调试器(如gdb)跟踪,处于断点调试状态。

    该状态的进程可通过SIGCONT信号恢复运行(如fg命令将后台暂停进程调至前台),适用于暂不明确进程作用时 —— 先暂停而非直接kill,降低误操作风险。

    操作示例:

    • 暂停进程:ping 223.5.5.5执行中按Ctrl+z,进程进入T状态;

    • 查看暂停任务:jobs命令(仅显示当前终端会话创建的任务);

    • 恢复进程:fg %1(将编号为 1 的暂停任务调至前台继续运行);

    • 彻底终止:Ctrl+c直接终止前台进程,或kill命令发送终止信号。

  4. D(Uninterruptible Sleep,不可中断休眠状态)
    进程因等待 “不可中断的系统资源”(如磁盘 I/O、硬件设备响应)而进入深度休眠,不响应任何外部信号(包括kill -9)。其设计目的是确保关键资源操作的原子性(如 MySQL 执行大量数据写入时,需等待磁盘同步完成,避免数据一致性问题)。

    注意:D状态进程虽不直接占用 CPU,但会锁定相关资源,若长期存在可能暗示硬件故障(如磁盘读写超时)。

  5. Z(Zombie,僵尸状态)
    子进程已终止(退出),但父进程未调用wait()系列系统调用回收其资源(如进程 ID、退出状态等),导致其残留于进程表中。僵尸进程不占用 CPU、内存等实际资源,但会消耗进程表项(系统进程 ID 数量有限),积累过多可能导致新进程无法创建。

状态辅助符号

除核心状态外,ps命令还会显示以下符号,用于描述进程的附加属性:

  • s:进程为会话首进程(Session Leader),通常是进程组的父进程,负责管理整个进程组的生命周期(如终端启动的命令进程多为会话首进程)。

  • <:进程运行在高优先级(对应S<状态,优先级值低于默认,Linux 优先级范围为 - 20~19,值越小优先级越高)。

  • N:进程运行在低优先级(对应SN状态,优先级值高于默认)。

  • +:进程属于前台进程组,直接接收终端输入(如当前终端执行的ls命令进程)。

  • l:进程包含多个线程(Lightweight Process),多线程进程可并行处理多个任务(如微信同时运行文字聊天、视频通话等功能,分别由不同线程执行),提升 CPU 利用率与响应速度。

结合pstop等工具查看进程状态变化,通过状态标识可快速判断进程是否正常运行、是否存在资源竞争、是否需要干预(如终止僵尸进程、排查 D 状态进程的资源瓶颈)。

进程控制:kill 命令

kill 命令通过向进程发送 信号(signal) 实现进程控制(终止、暂停、重启等),核心语法为:

1
kill [参数] <进程标识符(PID)>
核心参数说明
  • -l:列出所有可用信号(共 64 种,格式如 1) SIGHUP 9) SIGKILL)。

  • -s <信号>:指定发送的信号(可用名称或编号,如 -s SIGKILL-9)。

  • -p:仅输出目标进程的 PID,不发送任何信号(用于验证进程存在性)。

常用信号及场景
信号名称编号功能说明
SIGHUP1通知进程重新加载配置文件(如 nginx 服务重载)。
SIGINT2中断进程(通常由 Ctrl+C 触发,可被进程捕获处理)。
SIGKILL9强制终止进程(不可被捕获或忽略,适用于无法正常终止的进程)。
SIGTERM15优雅终止进程(默认信号,允许进程释放资源后退出,优先推荐使用)。
SIGSTOP19暂停进程(不可被忽略,需配合 SIGCONT 恢复)。
SIGCONT18恢复被 SIGSTOP 暂停的进程。
注意事项
  1. 权限要求:仅进程所有者或 root 可发送信号(普通用户无法终止其他用户的进程)。

  2. 强制终止风险SIGKILL(信号 9)可能导致数据丢失(如未保存的文件),尤其对存储服务(如数据库)需谨慎使用。

  3. 信号重试:部分守护进程可能忽略 SIGTERM,可先尝试 SIGTERM,无效再用 SIGKILL

系统平均负载

平均负载定义为 单位时间内,系统中处于「可运行状态(R)」和「不可中断状态(D)」的平均进程数(即活跃进程数),与 CPU 使用率无直接关联:

  • 可运行状态(R):正在占用 CPU,或等待 CPU 调度的进程(ps命令可见)。

  • 不可中断状态(D):等待硬件 I/O 响应的进程(如磁盘写入时的保护机制,中断会导致数据一致性问题,ps命令可见为D状态)。

系统平均负载的合理范围

系统平均负载的合理范围与 CPU 核心数强绑定。理想状态:平均负载 ≈ CPU 核心数(每个核心恰好运行 1 个进程)。不同核心数下,相同负载的意义截然不同:

CPU 核心数平均负载 = 2 的含义
4 核CPU 使用率 50%(50% 资源空闲)
2 核CPU 使用率 100%(资源刚好用满)
1 核CPU 使用率 200%(50% 进程需等待 CPU)
时间维度的解读

平均负载包含 1 分钟、5 分钟、15 分钟 三个值,需结合判断趋势:

  • 三者接近 → 负载平稳;

  • 1 分钟值 ≫ 15 分钟 → 近期负载突增(需紧急排查);

  • 1 分钟值 ≪ 15 分钟 → 近期负载下降(关注历史瓶颈)。

告警建议:当平均负载超过 CPU 核心数的 70% 时,建议介入分析(需结合历史数据动态调整阈值)。

与 CPU 使用率的区别

平均负载涵盖 等待 CPU、等待 I/O、进程调度 的进程,而 CPU 使用率仅统计 CPU 繁忙程度,二者在不同场景下表现不同:

序号负载升高场景平均负载变化use%sys%wait%CPU 整体使用率磁盘 IO 消耗
01CPU 密集型进程升高消耗多消耗少消耗少使用率高(某个核心)磁盘消耗小
02IO 密集型进程升高消耗少消耗多消耗多使用率低磁盘消耗大
03大量进程产生升高消耗多消耗少消耗多使用率高(所有核心)磁盘消耗小
问题排查核心思路
  1. 查看负载:通过 uptime/top 获取 1/5/15 分钟负载值,判断趋势。

  2. 分析 CPU:用 mpstat 查看多核负载、iowait 等指标,定位瓶颈类型(CPU 计算 / IO 等待)。

  3. 定位进程:通过 pidstat/top 追踪高负载进程(CPU/IO 占用异常的进程)。

  4. 日志溯源:结合进程所属服务的日志,分析代码逻辑或资源配置问题。

压力测试与监控工具

stress是Linux系统压力测试工具,可以用作异常进程模拟平均负载升高的场景。

mpstat:是多核CPU性能分析工具,用来实时查看每个CPU的性能指标,以及所有CPU的平均指标;

pidstat:是常用的进程性能分析工具,用来实时查看进程的CPU、内存、1/0以及上下文切换等性能指标;

1
yum install -y sysstat stress  # sysstat含mpstat/pidstat,stress用于压力测试

系统管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# history 查看历史命令
history -c #清除历史记录(慎用)

#关机命令 --关闭虚拟系统
shutdown -h now #立即关机
shutdown -h 0 #立即关机
shutdown -h now #立即关机
shutdown -h 5 #五分钟之后关机
init 0 #立即关机
half #立即关机

#重启命令
shutdown -r 0/now #立即重启
init 6 #立即重启
reboot #立即重启

#修改主机名(修改之后要bash命令刷新)
hostname name #临时修改
hostnamectl set-hostname name #永久修改

#2> 错误重定向
command 2>/dev/null

#which 查找$PATH中设置命令及安装文件目录所在位置
which cat

#export 设置环境变量,使其在当前 shell 及子进程中生效
#临时设置
export NAME # 导出已存在的变量为环境变量
export NAME=value # 定义并导出变量 “=”两侧不能有空格
NAME=value; export NAME # 等价写法
unset NAME # 删除变量
#永久设置
echo 'export JAVA_HOME="/opt/java"' >> /etc/profile # 对所有用户生效
echo 'export PATH="$PATH:~/.local/bin"' >> ~/.bashrc # 仅对当前用户生效

#env
env | grep NAME # 检查环境变量

#alternatives 管理系统命令的多版本实现,避免文件冲突
alternatives --config <命令名> # 手动选择版本
alternatives --remove <名称> <路径> # 移除版本
alternatives --display <名称> # 查看所有可用版本
alternatives --install <链接> <名称> <路径> <优先级> # 添加新版本

#crontab 设置周期性执行的任务
crontab -e #编辑当前用户的 cron 表(首次使用会选择编辑器)。
crontab -l #列出当前用户的所有定时任务。
crontab -r #删除当前用户的所有定时任务(谨慎使用)。
crontab -u user -e #以 root 身份编辑指定用户的 cron 表(需 root 权限)。
#时间格式:[分钟] [小时] [日期] [月份] [星期] command
#通配符与特殊符号:"*":匹配所有值 | ",":分隔多个值 | "-":指定范围 | "/":指定间隔
#相对时间:@daily | @weekly | @monthly | @reboot

# free 查看空间使用情况
free -h

# df 查看磁盘使用情况
df -h

#ps
a # 显示现行终端机下的所有程序,包括其他用户的程序。
-A # 显示所有程序。
c # 列出程序时,显示每个程序真正的指令名称,而不包含路 径,参数或常驻服务的标示。
-e # 此参数的效果和指定"A"参数相同。
e # 列出程序时,显示每个程序所使用的环境变量。
f # 用ASCII字符显示树状结构,表达程序间的相互关系。
-H # 显示树状结构,表示程序间的相互关系。
-N # 显示所有的程序,除了执行ps指令终端机下的程序之外。
s # 采用程序信号的格式显示程序状况。
u # 以用户为主的格式来显示程序状况。
x # 显示所有程序,不以终端机来区分
ps aux #USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND
ps -ef #UID, PID, PPID, C, STIME, TTY, TIME, CMD
# 若关注资源占用和用户名,用 ps aux;若需分析进程关系或用户 ID,用 ps -ef

#设置别名
alias eth0='cat /etc/sysconfig/network-scripts/ifcfg-ens33'
#取消别名
unalias eth0
#永久设置
alias eth0='cat /etc/sysconfig/network-scripts/ifcfg-eth0' >> /etc/profile

#timedatectl --修改时区信息,以及显示系统时间 内容比较详细
#date --快速简介显示时间信息
#"%Y" 年year| "%m" 月mouth | "%d" 日day | "%H" 时hour | "%M" 分min | "%S" 秒sec | "%F" 年-月-日
touch `date +%F`.txt

#jobs bg fg
jobs #用于查看后台运行启动
bg #将进程信息放入后台运行
fg #将进程信息放入前台运行

#uname [选项]
-a 或 --all #显示全部系统信息,涵盖系统名称、主机名、内核版本、处理器类型等内容。
-s 或 --kernel-name #显示内核名称,像 Linux、Darwin(macOS)等。
-n 或 --nodename #显示主机名,也就是计算机在网络中的标识名称。
-r 或 --kernel-release #显示内核版本号,例如 5.15.0-76-generic。

tail /var/log/messages #查看系统报错日志

文件管理

文件类型

image-20250714181833893

①文件属性索引节点 --inode(唯一的)–身份证号
②文件属性信息和文件权限信息
③文件硬链接数:查看文件数据信息的多个门(类似于挂载)
④文件属主信息:文件管理者/文件创建者
⑤文件属组信息/所属用户组信息: 便于进行权限整体分配
⑥文件数据信息大小尺寸
⑦文件数据最后修改时间信息(Mtime)

文件类型:告诉系统管理者这个文件是什么类型 f(-) d c b s p l

文件类型字符含义
普通文件-文本 图片等
目录文件d目录
链接字文件|==Windows 桌面快捷方式
块设备文件b存储数据以供系统存取的接口设备,简单而言就是硬盘。
字符设备文件c即串行端口的接口设备,例如键盘、鼠标等等。
套接字文件s这类文件通常用在网络数据连接。可以启动一个程序来监听客户端的要求,客户端就可以通过套接字来进行数据通信。第一个属性为 [s],最常在 /var/run目录中看到这种文件类型
管道文件pFIFO也是一种特殊的文件类型,它主要的目的是,解决多个程序同时存取一个文件所造成的错误。FIFO是first-in-first-out(先进先出)的缩写。

image-20250719173617460

软连接与硬链接:

软连接 l

硬链接 f

软连接:可以方便调取数据信息

复制连接的时候注意 复制的原文件的inode 是真实的文件

注意: 软链接的inode 和原文件的inode 是不一样的

​ 硬链接的inode和原文件的inode是完全一样的

软链接是一个新的文件 删除不会有影响

删除硬链接会删除原文件(如果有多个硬链接,删除到最后一个硬链接会删除原文件)

修改硬链接 即修改原文件

文件管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#1 mkdir
mkdir directionName #创建目录
mkdir {src,tools} #同时创建两个文件夹
mkdir -p a/b/c/ #创建多级目录

#2 ls ll
ls -l #查看目录下的文件属性信息 等于ll
ls -lh #以人类可读方式显示文件大小信息 等于ll -h
ls -a #查看目录下所有的数据信息 包含隐藏文件
ls -li #查看文件属性索引节点indode 等于ll -i

#3 cd #带'/'绝对路径,不带'/'相对路径
cd ~ #返回家目录 或直接 cd
cd / #返回根目录
cd .. #切换至上级目录
cd - #切换至上次所在目录
cd ~user #进入到用户根目录

# pwd #查看当前所在目录

#4 rm
rm -r filename filename #递归删除
rm -f #强制删除(无需确认)

#5 cp
cp /路径/旧文件 /路径/新文件
cp -r /路径/目录 /路径/目录 #拷贝目录下的所有文件到另一目录
-a #保持文件原有属性,该选项通常在复制目录时使用,它保留链接、文件属性,并递归地复制目录
cp a.txt b.txt #拷贝并改名


#6 mv
mv 文件/目录 新目录/
mv a b #修改文件名

#7 touch
touch filename #创建新文件
touch {filename1,filename2} #同时创建
touch {1..5}.txt #创建1.txt 2.txt 3.txt 4.txt 5.txt

#8 cat
cat -n filename #[带行号]查看文件内容
cat test.txt >> README #将test.txt的内容追加到README文件中
cat>>a<<EOF #追加新内容
> hello
> EOF
cat>a<<EOF #覆盖原始内容
> world
> EOF
head [-n] #查看n行(默认10行)
tail [-n] #查看末尾n行(默认10行)
tail -f #动态查看文件,可用于追踪日志文件信息变化

#9 重定向
echo "123456">hxjl.txt #覆盖重定向
echo "123456">>hxjl.txt #追加重定向

#10 echo
echo -e #激活转义字符
echo -E #不激活转义字符
echo $envname #打印环境变量
echo "this is test" > test.txt #写入文件

#11 grep
grep [-参数] string filename #文件中筛选字符串;
-i #不区分大小写
-n #显示行号
-c #统计匹配的行数
-v #排除指定信息

#wc [选项] [文件...]
-l #只显示行数(lines)
-w #只显示单词数(words)
-c #只显示字节数(characters)
-m #只显示字符数(包括多字节字符,如中文)
-L #显示最长行的长度

#12 tree 展示目录下的结构

#13 lrzsz
rz -y #从Windows上传文件到Linux

#14 wget
wget url #下载Web内容到本机

#15 file
file fileName #查看文件类型/属性

#16 rpm RPM是Red Hat公司随Redhat Linux推出了一个软件包管理器,通过它能够更加轻松容易地实现软件的安装。
#常见用法:
rpm -ivh <rpm包名> #安装软件
rpm -e <rpm包名> #卸载安装
rpm -Uvh <rpm包名> #升级一个rpm
rpm -qi <rpm包名> #显示软件安装信息
rpm -qa | grep xxx #查询软件是否安装(包括相关依赖)
rpm -qc <包名> #仅列出包的配置文件
rpm -qd <包名> #仅列出包的文档文件(手册、README等)
rpm -qlp <RPM文件路径> #查询未安装的RPM包内包含哪些文件
rpm -q --scripts <包名> #查看包的安装/卸载脚本
-i, --install #安装软件包 rpm -ivh package.rpm
-v --verbose #列出更多详细信息,安装进度 rpm -v install package.rpm
-h, --hash #安装时列出hash标记 (与 -v连用) rpm -ihv package.rpm
-U, --update #升级软件包 rpm -Uvh new-package.rpm
-e, --erase #卸载软件包 rpm -e package-name
-V, --verify #校验软件包文件完整性 rpm -V httpd
-l #列出文件 (list files)
test #安装测试,并不实际安装
-q, --query #查询软件包信息 rpm -q httpd
-a, --all #查询/校验所有的安装包
-p, --package #查询/校验一个安装文件
-l, --list #列出安装文件
-d, --docfiles #列出所有文档文件
-f, --file # 查询/校验安装包中所包含的文件

#17 stat
stat filename #查看文件属性(Size、Blocks、Inode、Atime、Mtime、Ctime等)

#18 cut
-c n1-n2 #截取n1到n2的字符

#19 find
find 查找路径 选项参数(查找数据条件) 操作语句
-mtime +10 #10天前
-mtime -10 #10天内
-name "c.sh"#文件名
-name "hxjl*.txt"#支持正则
-type d #文件类型
! -type d #取反
-size ±1M #文件大小
-perm 644 #文件权限
-exec ls -l {} \; #执行命令

#locate 基于数据库快速查找文件,比 find 更高效
-i #忽略大小写(如 locate -i readme 匹配 README 和 readme)。
-w #按整词匹配(如 locate -w /etc 仅匹配 /etc 目录而非 /etc/passwd)。
-c #只返回匹配的文件数量,不显示文件名(如 locate -c bashrc)。
-e #只显示存在的文件(过滤已删除但仍在数据库中的记录)。
--regex #使用正则表达式匹配(如 locate --regex '.*\.(jpg|png)')。
locate *.pdf # 匹配所有 PDF 文件
locate -i -e 'apache2' # 忽略大小写且只显示存在的文件
locate /data/ | grep '/data/[^/]*\.log$' # 查找 /data 目录下一级子目录中的 log 文件
locate "$(pwd)/*.txt" #查找当前文件夹下所有txt文件
#locate的速度比find快,它并不是真的查找,而是查数据库,一般文件数据库在/var/lib/mlocate/mlocate.db中,所以locate的查找并不是实时的,而是以数据库的更新为准,一般是系统自己维护,也可以手工升级数据库 ,命令为:updatedb


#20 tar
-z #表示打包的同时使用gzip的方式压缩
-j #以 bzip2 方式压缩打包
-c #表示创建一个压缩包文件
-v #表示 显示操作过程
-f #识别压缩路径信息
-t #查看压缩包内文件 tf
-x #解压 zxvf
-tf #不解压的方式查看压缩的内容
-zxvf #解压压缩包
-cvf #打包
-rvf #追加到已存在包
-xvf #解压包
tar -zcvf name.tar.gz file1 ... filen #打包再压缩成gzip
tar -zxvf name.tar.gz #解压缩在取消打包
tar -jcvf name.tar.gz file1 ... filen #打包再压缩成bzip2
tar -jxvf name.tar.bz2 -C /path/ #解压到指定目录
#不可以用find 作批量压缩命令
#find 路径... -exec tar {} \; ×
#会造成压缩数据信息的覆盖!
#压缩数据时,如果使用绝对路径压缩数据,要把"/"移除.如果有"/"只能压缩到根目录下,没有"/"可以将文件压缩到指定目录(不懂)

#21 zip
-r #递归地将一个目录及其所有子目录和文件压缩到ZIP文件中
-q #在压缩文件时启用静默模式,即不显示压缩过程的详细信息
-d #从现有的ZIP文件中删除指定的文件或目录
-u #用于更新现有的ZIP文件,将新的文件或修改后的文件添加到ZIP存档中
-f #用于刷新(更新)现有ZIP文件中的指定文件。
-m #用于移动(归档)文件到一个ZIP压缩文件中,并在移动后将源文件删除。
-e #用于对ZIP压缩文件进行加密。
-z #为压缩文件添加注释
zip -r 压缩包名.zip 文件1 文件2 文件n
zip -r test.zip /home/test -x "/home/test/test01/*" #排除test01目录 -x 指定排除目录,注意没有双引号将不起作用。
zip -r test.zip test/ -z #添加注释信息。添加完成后输入回车后输入 . 之后再输入回车来结束

# gzip 和 bzip2
gunzip a.txt.gz
gzip -d a.txt.gz
bunzip2 a.bz2
bzip2 -d a.bz2

#ln
ln /etc/services /data/link_hard #创建硬链接
ln -s /etc/services /data/link_soft #创建软链接

用户及权限管理

用户介绍

用户信息: 可以作为系统数据或者程序进程操作管理者

用户组信息:可以将多个系统用户进行整合,方便统一对多个用户的权限进行管理

用户

字符含义
u所属主 uid
g所属组 gid
o其他人 others
a所有人 all

用户相关文件信息配置文件:/etc/passwd

image-20250719223400503

以:为分隔符 分为若干部分

1
用户名:密码占位符:用户ID(UID):组ID(GID):用户描述:家目录:登录Shell
  • 用户名:字符串(如root),用于用户登录,长度限制为 32 字符。

  • 密码占位符:通常为x,表示密码已加密存储在/etc/shadow中。若为空则表示无需密码登录(危险)。

  • UID:整数,0 为 root 用户,1-999 为系统用户,1000 + 为普通用户。

  • GID:对应/etc/group中的主组 ID。

  • 用户描述:可选信息(如John Doe),通常用于注释。

  • 家目录:用户登录后的默认目录(如/home/user),root 用户为/root。

  • 登录 Shell:用户登录后使用的 Shell 程序(如/bin/bash),/sbin/nologin表示禁止登录。

用户加密密码和密码策略:/etc/shadow

1
用户名:加密密码:最后修改日期:最小修改间隔:最大修改间隔:警告期:非活跃期:过期日期:保留字段

加密密码使用$id$salt$hash 格式存储(如 $6$... 表示 SHA-512),!* 表示账户锁定。

用户组信息:/etc/group

权限介绍

字符权限
w—4写权限
r----2读权限
x----1执行权限(脚本文件先赋权才能再执行)

image-20250719211822282

r 读权限 4

  • 针对文件:利用此权限可以看到文件中的内容 cat

  • 针对目录:可以看到目录下有什么数据 ls/目录

w 写权限 2

  • 针对文件:利用此权限可以编辑文件中的内容 vim echo> >>

  • 针对目录: 利用此权限可以在目录中创建 删除文件信息 修改文件名称信息

x 执行权限 1

  • 针对文件:利用此权限 执行脚本信息

  • 针对目录:利用此权限可以切换到目录中

另 X:针对目录加执行权限,文件不加执行权限(因文件具备执行权限有安全隐患)

企业真实场景权限配置:

默认配置:

文件权限: 644 属主拥有读和写写权限 属组和其他用户只有读权限

目录权限: 755 属主拥有查看编辑进入权限 属组和其他用户只有查看进入权限

严格权限:

文件权限: 600 只有属主有读和写权限

目录权限: 700 只有属主有读写和进入权限

特殊权限

Linux 中的文件权限除了常见的读(r)、写(w)、执行(x)权限外,还有三个特殊权限SetUID(SUID)、SetGID(SGID)和Sticky Bit。它们用于解决一些特定的场景需求,通常设置于可执行文件或目录上,提供额外的权限控制功能。


SetUID(SUID)

  • 符号表示: s(出现在文件所有者的执行权限位置)

  • 八进制表示: 4(如 4755

  • 作用:

    • 可执行文件设置了 SUID 权限时,任何用户在执行该文件期间,会临时获得该文件所有者的权限。
    • 核心目的:允许普通用户以文件所有者的身份执行特定任务(通常是需要特权才能完成的任务)。
  • 经典例子: /usr/bin/passwd

    • 普通用户(如 user1)需要修改自己的密码,密码最终存储在 /etc/shadow(该文件只有 root 可读写)。
    • passwd 命令被设置了 SUID 且所有者是 root(权限 -rwsr-xr-x)。
    • user1 执行 passwd 时,进程临时获得 root 权限,从而能修改 /etc/shadow
  • 设置与查看:

    • 设置:chmod u+s 文件名chmod 4xxx 文件名 (e.g., chmod 4755 myprogram)
    • 查看:如果所有者原本有 x 权限,ls -l 中所有者执行位显示为 s,如果所有者原本没有 x 权限,则执行位显示为 S
  • 重要安全提示: SUID 权限非常强大且危险性很高。不当设置(尤其是对脚本或不可信程序)会带来严重安全漏洞。应仅授予绝对必要且经过严格审查的可执行文件。


SetGID(SGID)

  • 符号表示: s(出现在所属组的执行权限位置)

  • 八进制表示: 2(如 2755

  • 作用(取决于应用对象):

    • 应用于可执行文件:
      • 与 SUID 类似,但作用于
      • 任何用户在执行设置了 SGID 的文件时,会临时获得该文件所属组的权限。
      • 目的:允许用户以文件所属组的身份执行任务(通常用于共享资源访问)。
    • 应用于目录:
      • 这是 SGID 更常见且重要的用途
      • 在设置了 SGID 的目录中,任何用户在此目录下创建的新文件或子目录,其所属组自动继承该目录的所属组,而不是用户自己的默认主组。
      • 核心目的:强制协作共享。确保在共享目录中创建的所有文件都属于同一个特定组,方便组成员共同管理,无需手动修改组权限。
  • 经典例子(目录): 项目共享目录 /shared/projectX

    • 设置所属组为 projectx-teamchgrp projectx-team /shared/projectX
    • 设置 SGID:chmod g+s /shared/projectXchmod 2775 /shared/projectX
    • 现在,无论 userA(主组 groupA)还是 userB(主组 groupB)在 /shared/projectX 下创建文件 report.txt,该文件的所属组都会是 projectx-team(而不是 groupAgroupB)。
  • 设置与查看:

    • 设置:chmod g+s 文件名/目录名chmod 2xxx 文件名/目录名 (e.g., chmod 2775 sharedir)
    • 查看:如果组原本有 x 权限,ls -l 中组执行位显示为 s,如果组原本没有 x 权限,则组执行位显示为S
  • 安全提示: SGID 的风险通常低于 SUID,但仍需谨慎设置于可执行文件。在目录上的应用是安全且推荐的文件共享方式。


Sticky Bit

  • 符号表示: t(出现在其他用户的执行权限位置)

  • 八进制表示: 1(如 1777

  • 作用:

    • 仅对目录有意义。
    • 在设置了 Sticky Bit 的目录中,用户只能删除或重命名自己拥有的文件或目录,即使该目录的写权限 (w) 对其他用户开放(如 rwxrwxrwt)。
    • 核心目的:保护用户文件不被他人误删。在全局可写的目录中(如临时目录),防止用户随意删除他人的文件。
  • 经典例子: 系统临时目录 /tmp

    • 权限通常是 drwxrwxrwt
    • 所有用户都有读、写、执行权限。
    • 末尾的 t 表示 Sticky Bit 已设置。
    • 用户 user1 可以在 /tmp 创建文件 /tmp/user1file
    • 用户 user2 虽然对整个 /tmp 有写权限,但不能删除或重命名 /tmp/user1file(除非他是 root 或文件所有者 user1)。user2 可以创建自己的 /tmp/user2file
  • 设置与查看:

    • 设置:chmod o+t 目录名chmod 1xxx 目录名 (e.g., chmod 1777 /public/tmp)
    • 查看:如果其他用户原本有 x 权限,ls -l 中其他用户执行位显示为 t,如果其他用户原本没有 x 权限,其他用户执行位显示为T
  • 应用场景: 主要用于全局可写的共享临时目录(如 /tmp)。现代 Linux 中,对用户主目录 (~) 或普通共享目录(使用 SGID 管理组)通常不需要设置 Sticky Bit。


特殊权限总结

权限名称符号八进制值主要作用对象核心功能
SUIDs (所有者x位)4可执行文件执行时获得文件所有者权限
SGIDs (组x位)2可执行文件执行时获得文件所属组权限
目录目录下新建文件继承目录的组
Sticky Bitt (其他用户x位)1目录仅文件所有者可删除目录下的文件

查看系统中的特殊权限实例

  • SUID: ls -l /usr/bin/passwd (应看到 -rwsr-xr-x)

  • SGID (目录): ls -ld /var/mail (很多系统设置为 drwxrwsr-x)

  • Sticky Bit: ls -ld /tmp (应看到 drwxrwxrwt)

理解并正确使用这三个特殊权限对于 Linux 系统管理、权限规划和系统安全至关重要。务必谨慎设置 SUID,善用 SGID 管理共享目录,并在需要全局可写临时目录时使用 Sticky Bit。

sudoers权限分配

sudoers文件编辑与定位

执行visudo命令进入编辑界面后,可通过100gg快捷键快速定位至文件第 100 行附近(具体行数需根据系统版本及配置历史调整,通常用于找到预设的用户权限配置段),在此处可添加或修改用户的sudo权限规则。

验证sudoers配置正确性

配置完成后,需通过visudo -c命令验证/etc/sudoers文件的语法合法性,确保无格式错误:

1
2
[01:18:44 root@centon7 tmp]# visudo -c
/etc/sudoers:解析正确

若输出 “解析正确”,则说明配置文件语法无误,可正常生效。

查看系统用户与权限配置

/etc/sudoers中,用户权限规则的典型配置格式为:

1
用户名  ALL=(ALL)  /sbin/useradd,/bin/cat

其中:

  • ALL=(ALL)表示该用户可在所有主机上以所有用户身份执行命令;

  • 末尾的/sbin/useradd,/bin/cat为允许执行的具体命令列表(多命令用逗号分隔)。

查看用户sudo权限

对于已配置sudo权限的用户,可通过sudo -l命令查看自身被授权的具体操作,便于验证权限分配是否符合预期:

1
sudo -l

该命令会列出当前用户可通过sudo执行的所有命令及相关限制。

用户及权限管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#1 chmod
chmod XXX filename #数字赋权
chmod +x filename #添加执行权
chmod u+x,g+x,o+x filename #所有用户添加执行权==chmod +x filename==chmod a+x filename
chmod ug+w,o-w 1.txt 2.txt
chmod a=wx c.txt
chmod -R # 命令表示将某个目录下面所有的内容都增加相应权限

#id
id user #查看用户的 UID、GID 以及所属的用户组列表
id #查看自己的 UID、GID 以及所属的用户组列表
#whoami 可以查看当前系统操作者 即 登录的用户
#w 可以查看当前系统登录的用户信息 指的是 正在连接登录的用户信息

#useradd --添加用户信息
-c #设置用户备注信息
-u #设置指定用户所属主 uid
-g #设置用户所属组信息 gid
-G #设置用户所属的附加组
-M #设置用户不创建家目录(创建虚拟用户)
-s #设置用户是否能登录(创建虚拟用户)
useradd -g users -c "hr tom" tom

#su 切换用户:表示替换或转换用户身份 不完全切换
#su - 完全切换 用户相关环境变量信息会一并彻底切换
#sudo 提权,但需要先对特殊操作进行权限分配

#passwd 设置/更改密码
#面交互方式创建用户并设置密码(可利用脚本创建用户)
useradd xhy
echo 123456|passwd --stdin xhy

#userdel
userdel 用户名 #保留用户家目录的数据
userdel -r 用户名 #彻底删除用户信息

#usermod 参数 匹配信息 对象
-c #修改用户备注信息
-u #修改指定用户所属主 uid
-g #修改用户所属组信息 gid
-G #修改用户所属的附加组
-aG #添加用户到多个附加组
-M #修改用户不创建家目录(创建虚拟用户)
-s #修改用户是否能登录(创建虚拟用户)
-l #指定新的用户名
-d #可选参数,同时修改用户的家目录路径
-m #与 -d 配合使用,将原家目录内容移动到新路径
usermod -l newuser -d /home/newuser -m olduser

#chown:修改文件属主和属组
chown root /var/log/httpd.log # 更改文件所有者为root
chown :staff /home/user/file.txt # 仅更改文件所属组为staff
chown user1:group1 /data/project # 同时更改目录的所有者和组
chown -R 主:组 文件 #递归更改目录及其所有子文件、子目录的所有权
-h #仅更改符号链接本身的所有权,而非其指向的目标文件。

#gpasswd
gpasswd -a 用户 组 #添加用户到组
gpasswd -d 用户 组 #从组中删除用户

#chattr
chattr -i #重要文件上锁
chattr -i p #解锁(可以将命令名称改名,这样黑客就不知道怎么解锁了)

磁盘管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#1 du
du -sh filePath #文件存储到磁盘所占的空间(block)
#查看文件大小
du -h
du -ah
#查看分区
df -h

#df [选项] [文件或设备]
-h #以人类可读的格式显示磁盘空间大小
-T #显示文件系统类型
-i #显示 inode 信息
df #显示磁盘空间大小

#mount 挂载硬盘
#umount 取消挂载

vim使用

普通模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
yy     #复制光标所在行
nyy #数字yy 复制连续多行内容
p #粘贴复制/剪切的内容
np #粘贴n次复制/剪切的内容
dd #删除光标所在行
ndd #删除n行
D #删除本行内容,但是保留空行
dG #删除光标所在位置后的所有行内容
G #光标跳转到最后一行
gg #光标跳转到第一行
nG #光标跳转到第n行
$ #光标跳转当前行的末尾
0 #光标跳转到当前行的开头
Ctrl+u #undo
ctrl+r #redo

末行模式(命令模式):

1
2
3
4
5
6
7
8
9
10
:/要检索的内容      #检索
: %s/root/ROOT/g #替换
:set nu #显示行号
:q #不保存退出
:q! #强制不保存退出
:wq #保存退出
:wq! #强制保存退出
:e! #恢复到最初状态
:w a.txt #另存为
:w >> a.txt #内容追加到a.txt

每次进入vi就有行号编辑文件.vimc添加set nu

1
2
vi ~/.vimrc
set nu