DC娱乐网

每天一个 Linux 知识:后台运行 & 和 nohup

当我们在终端中直接执行命令(如python data_process.py、ping baidu.com)时,启动的进程

当我们在终端中直接执行命令(如python data_process.py、ping baidu.com)时,启动的进程默认是前台进程,其具有以下特点:

占据终端输入输出:前台进程会独占终端的标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。例如,执行ping baidu.com后,终端会持续输出 ping 结果,用户无法输入其他命令,需按Ctrl+C终止进程后才能恢复终端控制权;依赖终端生命周期:前台进程与启动它的终端强绑定——若关闭终端窗口(本地场景)或断开 SSH 连接(远程场景),系统会向进程发送SIGHUP(挂起信号),默认情况下进程会接收该信号并终止。

这种特性在处理短时间任务(如ls、pwd)时无影响,但对于需要运行数小时甚至数天的任务(如大数据处理脚本),前台运行会严重限制操作灵活性,甚至导致任务意外中断。

后台进程是指脱离终端直接控制、在后台独立运行的进程,其核心优势恰好解决了前台进程的局限性:

不占用终端控制权:后台进程启动后,终端会立即返回命令提示符,用户可继续执行其他命令,实现“多任务并行”;输出重定向可控:后台进程的标准输出和标准错误可通过重定向(>、>>)保存到文件,避免占用终端屏幕;部分后台进程可脱离终端依赖:结合nohup等工具,后台进程可摆脱终端生命周期限制,即使终端关闭也能持续运行。

Linux 中后台进程的状态可通过jobs命令查看,进程状态通常分为两种:

Running:后台正在运行的进程;Stopped:后台暂停的进程(可通过fg命令恢复到前台)。&符号

&是 Linux 命令行中最基础的后台运行符号——它无需安装额外工具,仅需在命令末尾添加即可将前台进程转为后台运行,适合处理“临时需要后台执行、且终端不关闭”的场景。

&的使用方式极为简单,语法格式如下:

命令 &

例如,将python data_process.py(假设该脚本需运行 1 小时)转为后台运行,只需执行:

python data_process.py &

当在命令末尾添加&时,Linux 内核会执行以下操作:

将进程的运行模式从“前台”改为“后台”,释放终端控制权;为进程分配一个唯一的“作业号”(Job ID,通过jobs命令查看)和 PID(进程 ID);进程的标准输出(stdout)和标准错误(stderr)默认仍会输出到当前终端(可通过重定向解决)。

执行上述命令后,终端会立即返回类似以下的信息:

[1] 12345 # [作业号] PID user@linux:~$ # 终端提示符,可继续输入其他命令

其中,[1]是作业号(后续可通过fg 1将进程调回前台),12345是进程的 PID(可通过kill 12345终止进程)。

&启动的后台进程默认会将标准输出(如脚本的打印信息)和标准错误(如报错信息)输出到当前终端,可能会干扰用户后续的命令输入。

解决方法是通过输出重定向将这些信息保存到文件中,常用格式如下:

# 将标准输出和标准错误合并重定向到 log.txt(覆盖写入) 命令 > log.txt 2>&1 & # 将标准输出和标准错误合并重定向到 log.txt(追加写入,推荐) 命令 >> log.txt 2>&1 & > log.txt:将标准输出(stdout,编号 1)重定向到log.txt,若文件已存在则覆盖;2>&1:将标准错误(stderr,编号 2)重定向到标准输出,即与标准输出一起写入log.txt;>>:改为追加写入,避免覆盖已有日志(适合长时间运行的任务)。

示例:将ping baidu.com后台运行并保存输出到ping.log:

ping baidu.com >> ping.log 2>&1 &

&的最大局限在于后台进程仍依赖终端——若关闭终端或断开 SSH 连接,系统会向所有由该终端启动的后台进程发送SIGHUP信号(默认触发进程终止)。例如,通过 SSH 远程执行python script.py &后,若断开 SSH 连接,script.py进程会立即停止。

这一特性决定了&更适合本地终端场景(如本地服务器,终端不关闭),或临时后台任务(如 10 分钟内可完成的脚本),不适合需要长期运行的远程任务。

使用&启动后台进程后,可通过以下命令管理进程状态:

jobs:查看当前终端的所有后台作业,输出包含作业号、状态和命令,示例:[1]+ Running python data_process.py & [2]- Stopped ping baidu.com >> ping.log 2>&1

其中,+表示“当前默认作业”(执行fg时会优先调回该作业),-表示“次默认作业”;

fg [作业号]:将后台进程恢复到前台运行。例如,fg 1会将作业号为 1 的进程调回前台,此时终端会再次被该进程占据,需按Ctrl+C终止或Ctrl+Z暂停;bg [作业号]:将暂停的后台进程恢复运行。例如,若通过Ctrl+Z将前台进程暂停(状态变为Stopped),可执行bg 1将其转为后台运行。nohup命令

nohup(全称“no hangup”,即“不挂起”)是专门用于解决“终端关闭导致进程终止”的工具。与&不同,nohup会忽略SIGHUP信号(终端关闭时系统发送的终止信号),让进程即使在终端断开后仍能持续运行,是远程服务器或长时间任务的首选工具。

nohup的基础语法如下,核心是在需要后台运行的命令前添加nohup:

nohup 命令 [参数]

例如,让python long_task.py(需运行 5 小时)脱离终端后台运行:

nohup python long_task.py

nohup的工作机制主要有两点:

忽略SIGHUP信号:当终端关闭或 SSH 断开时,系统会向进程发送SIGHUP信号;nohup会拦截该信号并“忽略”它,进程因此不会被终止;默认重定向输出:若未手动指定输出文件,nohup会自动将进程的标准输出和标准错误重定向到当前目录下的nohup.out文件(若文件已存在则追加内容)。

执行上述命令后,终端会输出提示信息:

nohup: ignoring input and appending output to 'nohup.out'

此时进程会以前台模式运行(仍占据终端),需按Ctrl+Z暂停后用bg转为后台,或直接结合&符号启动(更常用的方式)。

nohup单独使用时仍会占据终端(前台运行),因此实际场景中通常会将nohup与&结合——既实现“脱离终端”,又实现“不占终端”,这是最经典的后台运行组合方式。

# 推荐格式:nohup + 命令 + 输出重定向 + & nohup 命令 >> 日志文件 2>&1 &

各部分作用:

nohup:确保进程忽略SIGHUP信号,终端关闭不终止;>> 日志文件 2>&1:手动指定输出文件(避免使用默认的nohup.out,便于区分不同任务);&:将进程转为后台运行,释放终端控制权。

示例:远程服务器上运行shell备份脚本backup.sh,日志保存到backup.log,且终端断开后仍继续执行:

nohup sh backup.sh >> backup.log 2>&1 &

若需将日志保存到指定目录(而非当前目录),只需在日志文件名前添加路径即可。例如,将日志保存到/var/log/目录下(需确保有写入权限):

nohup python data_analysis.py >> /var/log/analysis.log 2>&1 &

由于nohup进程脱离了终端,jobs命令无法查看(jobs仅显示当前终端的后台作业),需通过ps或pgrep命令根据进程名或 PID 查询:

按进程名查询(如查找python进程):ps aux | grep python # 查看所有python进程,包含PID和命令详情 pgrep python # 仅返回所有python进程的PID 按 PID 查询(若已知 PID,确认进程是否存活):ps -p 12345 # 12345为进程PID,若输出结果则进程存活

nohup进程虽能脱离终端,但仍可通过kill命令终止(需知道进程 PID):

先查询 PID(如pgrep python找到目标进程 PID 为12345);发送终止信号(优先SIGTERM,无效再用SIGKILL):kill 12345 # 温和终止(默认SIGTERM,给进程清理时间) kill -9 12345 # 强制终止(SIGKILL,无响应时使用)