gpt4 book ai didi

linux - 在 bash 中捕获信号但不完成当前正在运行的命令

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:38:35 26 4
gpt4 key购买 nike

我想捕获一个信号(让我们关注 INT)并且不完成当前正在运行的命令,以便它在运行信号处理程序后完成。

假设我有以下脚本:

#!/bin/bash

READY=0

ctrl_c(){
READY=1
}

trap ctrl_c INT

while true; do
echo first sleep
sleep 1
echo second sleep
sleep 1
if [ $READY -ne 0 ] ; then
echo -e "\n$READY"
echo Exit
exit
fi
done

当我在 first sleep 后按 CtrlC 时,我会立即进入 second sleep,第二个sleep 1 脚本完成。

当我在 second sleep 之后按下 CtrlC 时(当第二个 sleep 1 正在运行时)然后我立即终止脚本。

如何确保此脚本在 整秒 内运行,即:sleep 不会终止?

最佳答案

您可以利用只有前台进程会收到信号这一事实来做到这一点。因此,您可以在后台运行您的命令,在前台捕获并 wait直到命令退出。

但除此之外,由于 wait will also exit on reception of a trapped signal :

When Bash is waiting for an asynchronous command via the wait builtin, the reception of a signal for which a trap has been set will cause the wait builtin to return immediately with an exit status greater than 128, immediately after which the trap is executed.

我们将不得不循环等待,仅在退出状态低于(或等于)128 时中止 -- 假设命令永远不会以高于 128 的状态退出。如果此假设在您的情况下无效,则此解决方案将不起作用。

我们可以将所有这些包装在一个函数中,我们称它为trapwrap :

trapwrap() {
declare -i pid status=255
# set the trap for the foreground process
trap ctrl_c INT
# run the command in background
"$@" & pid=$!
# wait until bg command finishes, handling interruptions by trapped signals
while (( status > 128 )); do
wait $pid
status=$?
done
# restore the trap
trap - INT
# return the command exit status
return $status
}

(说明:首先我们将 pidstatus 声明为整数,因此我们以后不必对它们进行转义。在将 SIGINT 的陷阱设置为先前定义的用户函数 ctrl_c 之后,我们在后台运行用户提供的命令并将其 PID 存储在 pid 中。我们 wait 在无限循环中完成 pid 因为 wait 也会在被困 SIGINT 处中断,在这种情况下它以状态 >128 退出。我们循环直到 wait<=128 退出,因为这表示退出状态实际上来自刚刚完成的后台进程。最后,我们恢复陷阱并返回命令退出状态。 )

然后,我们可以使用 trapwrap像这样:

#!/bin/bash

READY=0

ctrl_c() {
READY=1
}

while true; do
echo first sleep
trapwrap sleep 1

echo second sleep
trapwrap sleep 1

if [ $READY -ne 0 ] ; then
echo -e "\n$READY"
echo Exit
exit
fi
done

运行时,您会得到预期的结果:

first sleep
^C^C^C^Csecond sleep
^C^C
1
Exit

关于linux - 在 bash 中捕获信号但不完成当前正在运行的命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45590344/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com