Linux中如何同时运行多个后台作业?已掌握前后台切换
嘿,我懂你现在的困扰——明明把好几个作业都放到后台了,结果只有一个在跑,剩下的要么停着要么没动静。别着急,这其实是因为你可能没掌握正确的多后台作业启动姿势,我给你一步步拆解怎么实现多个后台作业同时运行:
大多数现代shell(比如bash、zsh)默认都支持多后台作业,但先快速检查一下:
- 输入
echo $SHELL确认当前用的shell - 输入
echo $-,如果输出里包含m,说明作业控制功能是开启的(默认都是开的);如果没有,输入set -m就能开启这个功能。
你之前可能是先启动一个前台作业,再用Ctrl+Z暂停然后bg转到后台,但这种方式如果前一个作业占着终端资源,可能会影响后续作业。更直接的方式是在每个命令末尾直接加&,让命令启动时就直接进入后台运行,不会阻塞下一个命令的执行:
# 启动第一个后台任务(比如一个耗时的脚本) ./long_running_task1.sh & # 紧接着启动第二个任务,不用等第一个结束 ./long_running_task2.sh & # 再来个ping测试当例子 ping example.com &
这样每个命令都会立刻在后台跑起来,互相不耽误。
输入 jobs 命令就能看到所有后台作业的运行情况,输出大概是这样:
jobs
[1] Running ./long_running_task1.sh & [2] Running ./long_running_task2.sh & [3] Running ping example.com &
如果某个作业显示Stopped,那大概率是它需要终端输入(比如等着输密码、选选项),这时候它会暂停运行。你可以用 fg %2(这里的%2是作业号,对应[2])把它调到前台处理,或者如果脚本不需要交互,就给它加个输入重定向:./needs_input.sh < /dev/null > log.txt 2>&1 &,让它从空设备读输入,避免卡住。
多个后台作业同时往终端输出内容的话,文字会混在一起很难看。最好把每个作业的输出单独重定向到日志文件:
# 把标准输出和错误输出都写到script1.log里 ./long_running_task1.sh > script1.log 2>&1 & # 第二个任务写到script2.log ./long_running_task2.sh > script2.log 2>&1 &
2>&1是把错误输出(文件描述符2)重定向到和标准输出(文件描述符1)同一个地方,这样所有日志都能存在对应的文件里,方便后续查看。
如果你关掉当前的终端窗口,默认情况下后台作业会被终止。如果想让它们一直运行,可以用这两个方法:
- 用nohup启动:
nohup ./long_running_task1.sh > script1.log 2>&1 &
nohup会让进程忽略“挂起信号”,就算你关闭shell,进程也能继续在后台运行。
- 给已启动的作业解绑shell:
先用jobs找到作业号,然后输入disown %1(%1是作业号),这样这个作业就和当前shell脱离关系,关闭终端也不会被终止。
- 要是后台作业一直处于
Stopped状态,先检查脚本里有没有需要交互的步骤(比如read命令),要么修改脚本去掉交互,要么用< /dev/null重定向输入。 - 如果你用的是tcsh这类小众shell,语法可能略有不同,但核心逻辑是一样的:用
&后台启动,jobs看状态,fg/bg切换前后台。
内容的提问来源于stack exchange,提问作者shuberman




