使用Ctrl-C终止程序而不终止父脚本

il_*_*mix 2 bash

我有一个bash脚本启动外部程序(evtest)两次.

#!/bin/bash

echo "Test buttons on keyboard 1"
evtest /dev/input/event1

echo "Test buttons on keyboard 2"
evtest /dev/input/event2
Run Code Online (Sandbox Code Playgroud)

据我所知,evtest只能通过Ctrl-C终止.问题是这也终止了父脚本.这样,对evtest的第二次调用永远不会发生.

如何关闭第一个evtest而不关闭脚本,以便第二个evtest实际运行?

谢谢!

PS:对于想要问"为什么不evtest手动运行而不是使用脚本?"的人来说,答案是这个脚本包含进一步的半自动硬件调试测试,因此启动脚本并执行所有操作更方便需要运行更多命令.

Mar*_*oij 6

您可以使用该trap命令"捕获"信号; 这相当于外壳的的signal()sigaction()C和大多数其他编程语言调用捕捉信号.

陷阱被重置为子shell,因此evtest仍将对SIGINT通过^C(通常通过退出)发送的信号起作用,但父进程(即shell脚本)不会.

简单的例子:

#!/bin/sh

# Run a command command on signal 2 (SIGINT, which is what ^C sends)
sigint() {
    echo "Killed subshell!"
}
trap sigint 2

# Or use the no-op command for no output
#trap : 2

echo "Test buttons on keyboard 1"
sleep 500

echo "Test buttons on keyboard 2"
sleep 500
Run Code Online (Sandbox Code Playgroud)

还有一个变体,它仍然允许你^C在一秒钟内按两次退出主程序:

last=0
allow_quit() {
    [ $(date +%s) -lt $(( $last + 1 )) ] && exit
    last=$(date +%s)
}
trap allow_quit 2
Run Code Online (Sandbox Code Playgroud)