暂停for循环后用bg恢复无法继续迭代,如何使其完成全部循环?
问题描述
使用Ctrl-Z暂停for循环后,若用bg命令将其恢复至后台运行,循环会在完成当前迭代后停止,无法进入下一次迭代;而用fg命令恢复则无此问题。即使在子shell中运行该循环也无法解决此问题。
背景场景为执行如下bash命令:
$ (for f in *.webm; do ffmpeg -fflags +genpts -i "$f" -map 0 -s hd1080 -c:v libx264 -preset slow -crf 20 -b:a 64k "${f%.webm}".mp4 > /dev/null 2>&1; done)
请问如何让该for循环在暂停并恢复至后台后仍能完整执行全部迭代?
解决方案
方法一:重定向循环的标准输入到/dev/null
问题根源是后台进程尝试读取终端时会触发SIGTTIN信号,导致进程暂停。将循环的标准输入重定向到空设备,即可避免这种情况:
$ (for f in *.webm; do ffmpeg -fflags +genpts -i "$f" -map 0 -s hd1080 -c:v libx264 -preset slow -crf 20 -b:a 64k "${f%.webm}".mp4 > /dev/null 2>&1; done) < /dev/null
这样用Ctrl-Z暂停后再执行bg,循环就能继续完成所有迭代。
方法二:用nohup启动循环
nohup会让进程脱离终端控制,同时忽略SIGHUP信号,适合后台长期运行:
$ nohup bash -c 'for f in *.webm; do ffmpeg -fflags +genpts -i "$f" -map 0 -s hd1080 -c:v libx264 -preset slow -crf 20 -b:a 64k "${f%.webm}".mp4 > /dev/null 2>&1; done' &
执行后即使退出当前终端,循环也能正常运行,暂停后用bg恢复也不会中断后续迭代。
方法三:写入脚本并后台执行
把循环逻辑保存为可执行脚本,再后台运行(同样建议重定向输入):
- 创建脚本文件
convert_webm.sh:
#!/bin/bash for f in *.webm; do ffmpeg -fflags +genpts -i "$f" -map 0 -s hd1080 -c:v libx264 -preset slow -crf 20 -b:a 64k "${f%.webm}".mp4 > /dev/null 2>&1 done
- 赋予执行权限:
$ chmod +x convert_webm.sh
- 后台运行:
$ ./convert_webm.sh < /dev/null &
内容的提问来源于stack exchange,提问作者Faxopita
相关产品推荐
相关产品推荐

