我有一个一千行的 Bash 脚本,每行包含一个ffmpeg
命令。我开始这个source script
并且运行得很好。
然而,当我尝试以各种方式控制这个脚本时,事情就完全出错了:
- 如果我
Ctrl + Z
暂停整个事情,只有当前的ffmpeg
命令暂停,并且下一个开始了!不是我想要的! - 如果我
Ctrl + C
停止一切,脚本会跳转到下一个ffmpeg
命令,并且我必须为脚本中的每一行按一次才能最终停止一切。纯粹是地狱。 - 我尝试
ps -ef
从另一个外壳程序中使用来找到source
从那里暂停/终止它的命令,但它不存在于列表中。
那么我怎样才能按照我希望的方式暂停/停止父脚本呢?或者,我如何才能以不同的方式执行脚本,以便我能够对其进行适当的控制?
答案1
尝试将脚本作为脚本运行,而不是获取它:
$ bash <scriptname>
答案2
问题是它ffmpeg
捕获了SIGINT
– 发送的 – 信号Ctrl+C,但在 bash 中被忽略,因为它不知道该信号是否也是为它准备的。
解决此问题的一种方法是添加一个陷阱获取脚本中的信号并在本地处理它。
例如,使用命令将陷阱添加到文件开头。然后使其可执行并运行它,或者通过$ bash script_file
-不是source
:
trap 'exit' INT
一条更奇特的线路,它通过消息和消息中止退出状态 130:
trap 'printf "Received SIGINT: Terminating.\n";exit 130' INT
然后:
$ ./file_with_commands
或者一个采购杀手脚本:
#!/bin/bash
trap 'printf "Received SIGINT: Terminating.\n";exit 130' INT
source "$1"
然后:
$ ./sourcetrap file_with_commands
一个简单的示例脚本可以是:
#!/bin/bash
if [[ $1 = trap ]]; then
trap 'printf "Received SIGINT: Terminating.\n";exit 130' INT
fi
ping localhost
ping localhost
ping localhost
- 无陷阱运行:
./script_name
- 带陷阱:
./script_name trap
然后Ctrl+C见证差异。
然后再次;不要source
这些脚本来自终端提示符。