带命令替换的Bash退出陷阱

带命令替换的Bash退出陷阱,bash,Bash,我需要一个bash函数来启动后台进程,并设置一个陷阱以在退出时终止它。比如: function start { <<<run process>>> & local pid="$!" trap "kill -9 $pid" EXIT echo $pid } 很明显,这会启动另一个bash进程,并且在函数返回后立即在其中执行陷阱 有什么方法可以让这个工作正常吗?如果我正确地理解了您的问题,那么在脚本退出后,您将立即终止进程

我需要一个bash函数来启动后台进程,并设置一个陷阱以在退出时终止它。比如:

function start {
    <<<run process>>> &
    local pid="$!"
    trap "kill -9 $pid" EXIT
    echo $pid
}
很明显,这会启动另一个bash进程,并且在函数返回后立即在其中执行陷阱


有什么方法可以让这个工作正常吗?

如果我正确地理解了您的问题,那么在脚本退出后,您将立即终止进程

这意味着进程将随脚本一起终止,而不是在子shell完成之前阻塞脚本

为了解决这个问题,我建议您使用SIGINT和SIGTERM来终止进程,而不是依赖EXIT终止进程

例如:

#!/bin/bash
function start {
    <<command>> &>/dev/null &
    local pid="$!";
    echo $pid;
    trap "kill -9 $pid" SIGINT SIGTERM
}
PID=$(start)
echo $PID;
#/bin/bash
功能启动{
&>/dev/null&
本地pid=“$!”;
echo$pid;
陷阱“杀死-9$pid”SIGINT SIGTERM
}
PID=$(开始)
echo$PID;
注意。在执行之前,不要忘记关闭
的任何输出。如果不这样做,这将与存储在$PID中的PID输出混淆。如果确实要回显此消息,请使用
1>&2
将其发送到stderr


希望这能有所帮助。

我终于找到了一个类似于@gniourf\u gniourf在评论中建议的解决方案。此外,我想推迟多个清理操作,直到脚本退出,因此我创建了一个陷阱,用于迭代如下列表:

exit_list=()
function on_exit {
    for line in "${exit_list[@]}" ; do
        $line
    done
}
trap on_exit EXIT
启动函数将PID存储在全局变量中(并且
exit_list
数组也是全局变量):

功能启动{
&
pid=“$!”
exit_list=(“kill-9$pid”“${exit_list[@]}”)
}

kill-9
是一种代码气味。任何半正常运行的进程都可以使用
-INT
-TERM
-QUIT
-HUP
之一终止。这些信号允许进程清理其混乱(如锁和临时文件等)。一个简单的可能性是不在子shell中运行命令:让它设置全局变量
start\u pid
,调用它,然后存储此全局变量以供以后重用。谢谢@Jens。我不确定我的过程是否正常,但我会看看是否有更好的方法来杀死它。@gniourf_gniourf,我认为这是个好主意。我还发现了这个描述了如何在不提交特定全局变量的情况下(使用
eval
)执行此操作。不,请不要使用
eval
!正如我所说的:函数全局设置变量
start\u pid
,调用函数后保存(或不保存)此变量以备将来使用。我的意图是在$(start)之后有更多的代码,这取决于辅助进程是否处于活动状态,并在完成后或出现错误时自动终止它。我相信SIGINT和SIGTERM不会提供这些。不过,感谢您提供有关命令输出的提示,我相信我在那里遇到了一个bug。
exit_list=()
function on_exit {
    for line in "${exit_list[@]}" ; do
        $line
    done
}
trap on_exit EXIT
function start {
    <<<run process>>> &
    pid="$!"
    exit_list=("kill -9 $pid" "${exit_list[@]}")
}