Linux常用命令--进程管理
摘要
-
本文介绍Linux进程管理等相关命令
-
本文基于
CentOS8(x86_64)
ps :查看进程
1 | # 与top命令类似,可以查看进程信息 |
-
ps 命令也可以查看指定进程的
线程
信息
1 | $ ps -Lp <pid> |
pstree :树状查看进行信息
1 | # 折叠展示,只展示父进程和子进程的数量 |
kill :终止进程
1 | # 正常关闭进程 |
信号量
- 通过
kill -l
可以查看所有信号的编号和名称
信号编号 | 信号名称 | 说明 |
---|---|---|
1 | SIGHUP | 挂起信号,通常用于通知进程终端断开或重新加载配置。 |
2 | SIGINT | 中断信号,通常由用户通过键盘 (Ctrl+C ) 发送,用于中断一个进程。 |
3 | SIGQUIT | 退出信号,通常由键盘 (Ctrl+\ ) 发送,要求进程生成核心转储并退出。 |
4 | SIGILL | 非法指令信号,表示进程执行了非法或未定义的机器指令。 |
5 | SIGTRAP | 陷阱信号,通常用于调试程序(如断点异常)。 |
6 | SIGABRT | 异常终止信号,进程调用 abort() 函数时触发。 |
7 | SIGBUS | 总线错误信号,通常由于未对齐的内存访问引发。 |
8 | SIGFPE | 浮点异常信号,例如除零或溢出。 |
9 | SIGKILL | 强制终止信号,无法被捕获或忽略,立即终止进程。 |
10 | SIGUSR1 | 用户自定义信号 1,用户或应用程序自定义用途。 |
11 | SIGSEGV | 段错误信号,表示进程访问了非法的内存地址。 |
12 | SIGUSR2 | 用户自定义信号 2,用户或应用程序自定义用途。 |
13 | SIGPIPE | 管道破裂信号,通常在写入一个已关闭的管道或套接字时触发。 |
14 | SIGALRM | 定时器信号,由 alarm() 函数触发,用于定时操作。 |
15 | SIGTERM | 终止信号,允许进程执行清理操作后终止。这个也是缺省的信号。 |
16 | SIGSTKFLT | 堆栈错误信号,主要用于硬件相关的堆栈操作(极少使用)。 |
17 | SIGCHLD | 子进程状态改变信号,当子进程退出或停止时触发。 |
18 | SIGCONT | 继续信号,用于恢复被暂停的进程。 |
19 | SIGSTOP | 暂停信号,无法被捕获或忽略,立即暂停进程。 |
20 | SIGTSTP | 终端暂停信号,通常通过键盘 (Ctrl+Z ) 发送。 |
21 | SIGTTIN | 后台进程尝试从终端读取输入时触发。 |
22 | SIGTTOU | 后台进程尝试向终端写入输出时触发。 |
23 | SIGURG | 紧急条件信号,通常用于套接字通信中的紧急数据。 |
24 | SIGXCPU | 超过 CPU 时间限制信号。 |
25 | SIGXFSZ | 超过文件大小限制信号。 |
26 | SIGVTALRM | 虚拟定时器信号,由 setitimer() 触发,用于进程执行时间的计时。 |
27 | SIGPROF | 统计定时器信号,用于程序性能分析。 |
28 | SIGWINCH | 窗口大小改变信号,终端窗口调整时触发。 |
29 | SIGIO | I/O 可用信号,表示文件描述符可用。 |
30 | SIGPWR | 电源故障信号。 |
31 | SIGSYS | 无效的系统调用信号。 |
-
从 SIGRTMIN(34)到 SIGRTMAX(64)的信号是实时信号,供用户或应用程序使用,具有更高的优先级和灵活性。
-
使用时,可以通过数字或名称来指定信号,例如
kill -9
或kill -SIGKILL
,当然也支持去掉SIG
的简称,例如kill -KILL
。 -
咋一看有很多,但实际上我们日常通过键盘能操作的就几个。
-
- SIGHUP:挂起信号,通常用于通知进程终端断开或重新加载配置。
1
2
3
4# 重新加载nginx配置文件
kill -HUP `cat /var/run/nginx.pid`
# 或者
sudo systemctl reload nginx-
- SIGINT:中断信号,通常由用户通过键盘 (
Ctrl+C
) 发送,用于中断一个进程。
- SIGINT:中断信号,通常由用户通过键盘 (
-
- SIGQUIT:退出信号,通常由键盘 (
Ctrl+\
) 发送,要求进程生成核心转储并退出。
- SIGQUIT:退出信号,通常由键盘 (
-
- SIGKILL:强制终止信号,无法被捕获或忽略,立即终止进程。
1
2# 强制终止进程
kill -9 `cat /var/run/nginx.pid`-
- SIGTERM:用于优雅的终止进程,通常由用户或应用程序发送,用于通知进程进行清理操作。这个也是缺省的信号。
1
2
3
4# 终止进程
kill -TERM `cat /var/run/nginx.pid`
# 或者
kill `cat /var/run/nginx.pid` -
进程的挂起和恢复
1 | ctrl+c :终止 |
进程运行优先级
-
进程优先级是 PRI(top中的PR),其表示程序被 CPU 执行的先后顺序,此值越小进程的优先级别越高
-
PRI 值不是 Nice 值,但是 Nice 值会影响优先级,
PRI(new) = PRI(old) + nice
,所以我们调整 Nice 值,就可以改变进程的优先级 -
linux下的进程调度优先级 Nice 是从 -20 到 19 ,一共 40 个级别,数字越大,表示进程的优先级越低。默认时候,进程的调度优先级是0。
1 | # 指定命令的运行优先级 |
at :执行一次的计划任务
-
/var/spool/at:at任务存放在该目录下
1 | # 启动at服务 |
-
用户限制:
/etc/at.allow
:如果文件存在,则只有此文件中列出的用户可以使用at命令
/etc/at.deny
:如果文件存在,则此文件中列出的用户不可以使用at命令
如果以上两个文件都不存在,则只有root用户可以使用at命令
如果以上两个文件都存在,但是都为空,则所有用户都可以使用at命令
crontab :周期性计划任务
-
systemctl start crond
:启动cron服务,默认启动 -
crontab -l
:显示当前用户下的计划任务 -
crontab -e
:编辑当前用户下的计划任务 -
/var/spool/cron
:计划任务保存在该路径下 -
/etc/cron.allow
与/etc/cron.deny
:用户限制,规则同at
-
格式:
分钟[0~59] 小时[0~23] 日期[1~31] 月份[1~12] 星期[0~6] commands
1 | # 每5分钟执行一次 |
systemctl :服务管理
-
centOS7以后使用
systemd
进行服务管理,其命令接口为systemctl
-
systemctl
兼容了service
,即systemctl
也会去/etc/init.d
目录下,查看、执行相关程序 -
如下centOS6及之前的服务启动方式,centOS7及之后仍然可以通过这种方式管理服务,实际上会重定向到systemctl命令
1 | service redis start |
-
systemd
的服务配置放在目录/usr/lib/systemd/system (Centos)
或/etc/systemd/system (Ubuntu)
-
配置目录下有多种类型文件
.mount
,.service
,.target
,.socket
,.timer
等等- 不同的文件类型代表不同的资源,统称为 Unit(单位),Unit 一共分成12种类型
1
2
3
4
5
6
7
8
9
10
11
12Service unit:系统服务
Target unit:多个 Unit 构成的一个组
Device Unit:硬件设备
Mount Unit:文件系统的挂载点
Automount Unit:自动挂载点
Path Unit:文件或路径
Scope Unit:不是由 Systemd 启动的外部进程
Slice Unit:进程组
Snapshot Unit:Systemd 快照,可以切回某个快照
Socket Unit:进程间通信的 socket
Swap Unit:swap 文件
Timer Unit:定时器 -
重点学习
.service
文件,其定义了一个服务,分为[Unit],[Service],[Install]三个小节
[Unit]:描述服务的元信息和依赖关系
指令名 | 说明 |
---|---|
Description |
服务的简要描述(推荐设置) |
Documentation |
文档链接,可是 URL 或 man page 名 |
Requires= |
硬依赖的其他 unit,若失败则本服务也失败 |
Wants= |
弱依赖,失败不影响当前服务 |
Before= |
本服务启动应在指定服务之前 |
After= |
本服务启动应在指定服务之后 |
Conflicts= |
指定服务不能同时运行(冲突) |
ConditionPathExists= |
若路径存在则运行,否则跳过服务 |
Condition... (系列) |
条件判断,如 ConditionKernelCommandLine= 、ConditionUser= 等 |
StartLimitBurst |
限制单位时间内最大重启次数 |
StartLimitIntervalSec |
限制重启频率(配合 Burst 使用) |
[Service]:定义服务的行为、运行方式、启动/停止命令等
指令名 | 说明 |
---|---|
Type= |
服务类型:simple 、forking 、oneshot 、notify 、dbus 、idle |
ExecStart= |
启动服务时执行的命令 |
ExecStop= |
停止服务时执行的命令 |
ExecReload= |
重载服务时执行的命令(如 nginx -s reload ) |
Restart= |
服务异常退出后的重启策略(on-failure 、always 等) |
RestartSec= |
重启前等待时间(秒) |
User= |
以指定用户身份运行服务 |
Group= |
以指定组身份运行服务 |
WorkingDirectory= |
设置工作目录 |
Environment= |
设置环境变量(如 Environment=JAVA_HOME=/opt/java ) |
EnvironmentFile= |
从文件中加载环境变量 |
PIDFile= |
指定服务主进程 PID 文件路径 |
TimeoutStartSec= |
启动命令最长等待时间 |
TimeoutStopSec= |
停止命令最长等待时间 |
KillSignal= |
停止服务时发送的信号(默认 SIGTERM) |
SendSIGKILL= |
是否在超时后发送 SIGKILL(默认 yes) |
KillMode= |
控制如何终止进程(如 control-group 、process ) |
StandardOutput= |
控制标准输出(如 journal 、syslog 、null ) |
StandardError= |
控制标准错误输出 |
LimitNOFILE= |
设置文件描述符上限等资源限制 |
ExecStartPre= |
启动前先执行的命令 |
ExecStartPost= |
启动后再执行的命令 |
ExecStopPost= |
停止后执行的命令 |
RemainAfterExit= |
启动脚本退出后服务仍保持 active 状态(用于 oneshot ) |
SuccessExitStatus= |
自定义哪些退出码视为成功 |
[Install]:定义服务如何集成到启动流程(开机启用)
指令名 | 说明 |
---|---|
WantedBy= |
绑定到哪个目标(如 multi-user.target ),用于 enable 开机启动 |
RequiredBy= |
强绑定,失败会阻止目标加载 |
Also= |
启用/禁用此服务时,也启用/禁用列出的其他 unit |
Alias= |
创建服务别名(可用 systemctl start <别名> 来代替) |
DefaultInstance= |
用于模板服务(@.service )的默认实例名 |
systemd Target 与传统 RunLevel 对照表
systemd Target |
传统 RunLevel | 说明 |
---|---|---|
poweroff.target |
0 | 关机。系统停止所有服务并关闭电源。等价于 runlevel 0 |
rescue.target |
1 | 单用户模式。挂载文件系统、提供 root shell,不启动网络等服务(等价 runlevel 1 ) |
multi-user.target |
3 | 多用户命令行模式,无图形界面。正常服务器模式(等价 runlevel 3 ) |
graphical.target |
5 | 多用户 + 图形界面。启动 display manager(如 GDM/XDM)(等价 runlevel 5 ) |
reboot.target |
6 | 重启。等价于 runlevel 6 (但 systemd 使用 isolate reboot.target ) |
emergency.target |
无 | 最低限度的系统,仅挂载 / ,只提供 root shell。不等价于任何传统 RunLevel(比 runlevel 1 更底层) |
default.target |
可配置 | 指向系统默认启动目标,通常是 graphical.target 或 multi-user.target |
halt.target |
(0) | 仅停止系统(不一定断电) |
shutdown.target |
(0/6) | 提供通用的关机目标,常在 halt , poweroff , reboot 前被调用 |
-
查看服务
1 | # 列出当前已经加载启动的 unit,如果添加 -all 选项会同时列出没有启动的 unit |
-
service :系统服务
1 | # 启动redis服务 |
小贴士
1 | # 查看系统启动耗时 |
-
target :类似于运行级别,支持多个target同时启动。target其实是多个unit的组合,系统启动说白了就是启动多个unit
1 |
|
小贴士
- 1.
systemd
主配置文件/etc/systemd/system.conf
- 2.开机会先加载
/etc/systemd/system/default.target
- 3.所有的
service
和target
都在/usr/lib/systemd/system/
目录下 - 4.
/etc/systemd/system/defaut.target
是一个软连接,软连接到了/usr/lib/systemd/system/multi-user.target
,它会加载/usr/lib/systemd/system/multi-user.target.wants
下面的service
- 5.查看一个
service
属于哪个target
,需要查看具体的service文件,如:cat /usr/lib/systemd/system/sshd.service
,看里面[install]
部分
rc.local :本地服务启动文件
-
centos8 之后默认是不开启
rc-local
服务的,而是推荐使用systemctl
来管理开机启动,但是仍然可以手动开启rc-local
服务
1 | # 如果该文件不存在就创建 |
使用 systemctl 来替换 rc.local
-
比如开机时以 ec2-user 身份运行 /home/ec2-user/Jenkins/start.sh 脚本。
-
如果编写到 /etc/rc.d/rc.local 中,则如下
1 | su - ec2-user -c /home/ec2-user/Jenkins/start.sh |
-
如果编写到 /etc/systemd/system/jenkins.service中,则如下
1 | [Unit] |
-
此时已经可以通过
systemctl
来管理 jenkins 了,如果你有自己的stop
和restart
脚本,可以配置如下
1 | [Unit] |
-
指令简介
指令 | 含义 |
---|---|
ExecStart |
启动 Jenkins 的脚本(模拟 su - ec2-user -c ) |
ExecStop |
停止 Jenkins 的脚本 (如果没有提供,systemd 会默认发送 SIGTERM 给主进程,让它优雅退出) |
ExecReload |
重启 Jenkins 脚本(如果没有提供,systemd 也能用 ExecStop + ExecStart 自动重启) |
Type=forking |
表示脚本会 fork 到后台运行(如 Jenkins 通常会这样做) |
RemainAfterExit=yes |
启动后保持服务为 active,即使脚本退出 ,一般只在 simple 或 oneshot 模式下使用,本示例不需要设置 |
Restart=on-failure |
如果脚本失败,systemd 自动尝试重启 |
User |
指定以哪个用户身份运行脚本 |
WorkingDirectory |
设置脚本运行时的工作目录(可选,但推荐设置) |
-
Restart 可选值
Restart 值 | 成功退出(exit 0) | 异常退出(exit ≠ 0) | 信号终止(如 SIGKILL) | Core Dump / Watchdog 故障 | 说明 |
---|---|---|---|---|---|
no (默认) |
✖️ 不重启 | ✖️ 不重启 | ✖️ 不重启 | ✖️ 不重启 | 永远不自动重启 |
on-success |
✅ 重启 | ✖️ 不重启 | ✖️ 不重启 | ✖️ 不重启 | 仅当进程正常退出时重启(很少使用) |
on-failure |
✖️ 不重启 | ✅ 重启 | ✅ 重启 | ✅ 重启 | 常用。非正常退出时重启 |
on-abnormal |
✖️ 不重启 | ✖️ 不重启 | ✅ 重启(信号终止) | ✅ 重启 | 仅当进程被信号或异常终止时重启 |
on-watchdog |
✖️ 不重启 | ✖️ 不重启 | ✖️ 不重启 | ✅ 重启(watchdog 故障) | 仅在 watchdog 超时才重启 |
on-abort |
✖️ 不重启 | ✖️ 不重启 | ✅ 重启(信号终止) | ✖️ 不重启 | 仅在收到信号(如 SIGTERM)时重启 |
always |
✅ 重启 | ✅ 重启 | ✅ 重启 | ✅ 重启 | 所有退出都重启(守护进程建议使用) |
-
Type 可选值
Type 类型 |
含义与行为 | 启动时 systemd 的行为 | 适用场景 | 示例 |
---|---|---|---|---|
simple (默认) |
直接启动 ExecStart 指定的命令,不等待子进程 |
执行后立即认为服务已启动 | 脚本/服务在前台运行,不会 fork 到后台 | ExecStart=/usr/bin/python3 app.py |
forking |
启动脚本fork 出后台进程并自行退出 | systemd 认为服务启动完成于脚本退出之后,主服务 PID 由其追踪 | 传统后台服务或使用 nohup /& 的脚本 |
ExecStart=/etc/init.d/nginx start |
oneshot |
用于执行一次性命令,命令运行完即结束 | 等待命令执行完毕再继续启动其他服务 | 初始化任务、配置脚本、挂载命令等 | ExecStart=/usr/bin/initialize.sh |
dbus |
启动服务后,等待其注册 D-Bus 名称 视为启动完成 | 服务必须使用 D-Bus 提供名称 | D-Bus 服务(如 NetworkManager) | BusName=org.freedesktop.NetworkManager |
notify |
启动服务后,等待其通过 sd_notify 告知已就绪 |
服务必须主动通知 systemd 启动完成 | 高级服务(如 systemd 自带服务) | NotifyAccess=main (需程序配合) |
idle |
等系统空闲时再启动,其他服务都初始化后执行 | 类似 simple ,但延迟执行 |
非关键服务、后台任务 | ExecStart=/usr/bin/postinit.sh |
-
管理服务
1 | # 重新加载配置 |
chkconfig :设置系统服务在哪些运行级别下开机启动
-
centOS7之后不再使用这种方式,而是使用
systemctl
,但是仍然可以在/etc/init.d
(实际上是/etc/rc.d/init.d
的软链)目录下创建管理脚本,然后通过chkconfig
进行管理
1 | chkconfig --list :查看全部系统服务的运行级别 |
rc.d
1 | tree /etc/rc.d/ |
ntsysv :通过界面设置服务是否开机启动
-
centOS7之后不再使用这种方式,而是使用
systemctl
,但是仍然可以使用其管理当前运行级别下的服务 -
运行命令后会弹出设置界面,服务前面有*号的表示开机启动,使用空格修改,Tab键进行跳转
1 | # 修改当前的运行级别下的服务 |
Linux运行级别
0:系统关机模式,系统默认运行级别不能设置为0,否则无法正常启动系统
1:单用户模式,也称为救援模式,root权限,用于系统维护,禁止远程登陆,类似Windows下的安全模式登录。
2:无网络支持的多用户模式
3:有网络支持的多用户模式(文本模式,工作中最常使用的模式)
4:保留,未使用
5:有网络支持的图形化模式,支持多用户模式,登陆后进入图形GUI模式或GNOME、KDE图形化界面,如X Window系统。
6:重启模式,重新引导系统,即重启
运行级别切换
1 | # 查看当前的运行级别,输出结果为: 上一次运行级别 当前运行级别 |
fuser :可以显示出当前哪个程序在使用磁盘上的某个文件、挂载点、甚至网络端口,并给出程序进程的详细信息
-
fuser通常被用在诊断系统的
resource busy
问题,通常是在你希望umount
指定的挂载点得时候遇到
1 | # 查看哪个进程在访问/mnt目录 |
查看进程启动时的环境变量
-
所有启动的进程都会在
/proc/
下创建以其进程IP命名的文件夹,其下为与当前进程相关为文件,其中environ
中的没人就是进程启动时的环境变量,比如我们查看elasticsearch
的进程
1 | $ pgrep -f elasticsearch |