Shell 支持作业控制,可以将任务放到后台运行,在前后台之间切换。这对于长时间运行的任务特别有用,可以让终端继续做其他事情。
前台任务:占用终端,运行时无法执行其他命令。
后台任务:在后台运行,不占用终端,可以继续输入命令。
在命令后加 &,将命令放到后台运行:
./long_task.sh &
sleep 100 &
输出示例:
[1] 12345
[1] 是作业号,12345 是进程 ID。
jobs 命令查看当前 Shell 的后台任务:
jobs
jobs -l
输出示例:
[1]- Running ./long_task.sh &
[2]+ Stopped vim file.txt
-l 显示进程 ID。
状态说明:
| 状态 | 含义 |
|---|---|
| Running | 正在运行 |
| Stopped | 已暂停 |
| Done | 已完成 |
+ 表示最近的任务,- 表示次近的任务。
Ctrl+Z 暂停当前前台任务,放入后台:
vim file.txt
# 按 Ctrl+Z
[1]+ Stopped vim file.txt
fg 命令将后台任务恢复到前台:
fg
fg %1
%1 指定作业号。
bg 命令将暂停的任务在后台继续运行:
bg
bg %1
普通后台任务在终端关闭时会被终止。nohup 可以让任务忽略挂起信号,终端关闭后继续运行:
nohup ./long_task.sh &
nohup ./script.sh > output.log 2>&1 &
默认输出重定向到 nohup.out 文件。
已经运行的后台任务可以用 disown 使其脱离终端:
./task.sh &
disown
disown %1
disown -h %1
-h 使任务忽略 SIGHUP,但仍属于当前 Shell。
查看已 disown 的任务:
jobs -l
disown 后任务不再显示在 jobs 列表中。
wait 等待后台任务完成:
./task1.sh &
./task2.sh &
wait
echo "所有任务完成"
等待特定任务:
./task.sh &
pid=$!
wait $pid
echo "任务 $pid 完成"
$! 是最后一个后台任务的 PID。
有时候需要让脚本在后台运行,但又想看到输出:
nohup ./script.sh > output.log 2>&1 &
tail -f output.log
nohup tar -czf backup.tar.gz /data > backup.log 2>&1 &
task1.sh &
task2.sh &
task3.sh &
wait
echo "所有任务完成"
# 启动任务
./long_script.sh
# Ctrl+Z 暂停
# 放到后台继续运行
bg
# 查看状态
jobs
# 需要时恢复到前台
fg
# 方法一:nohup
nohup ./server.sh &
# 方法二:disown
./server.sh &
disown -h %1
# 方法三:setsid
setsid ./server.sh
# 方法四:screen/tmux
screen -dmS server ./server.sh
while true; do
jobs -l
sleep 5
done
screen 和 tmux 是更强大的终端复用工具,可以创建多个虚拟终端,断开后会话保持:
# 创建新会话
screen -S mysession
tmux new -s mysession
# 分离会话
# Ctrl+A D (screen)
# Ctrl+B D (tmux)
# 重新连接
screen -r mysession
tmux attach -t mysession
# 列出会话
screen -ls
tmux ls
& 将命令放到后台运行