对 Bash 脚本的作业控制

对 Bash 脚本的作业控制

我有一个一千行的 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这些脚本来自终端提示符。

相关内容