1

语境:

说我有:

(
#outer subshell
    {
    #inner command group, pipe-connected to ensure simultaneous invocation
        do_first_thing
        #die, somehow
    } | { 
    #inner command group, pipe-connected to ensure simultaneous invocation
        sleep 10
        do_second_thing
    }
)
echo "out"

我有一个外部子shell(不必是一个;它可以是一个命令组,也可以完全删除)。在那里面,我有两个同时被调用的管道连接的命令组。我希望两个组都开始执行,然后,当第一组完成时(第二组仍然在运行sleep),我希望外部子shell的执行停止,即#die, somehow行所在的位置。

问题:

我应该怎么做才能确保#die, somehow到达该行时,#outer subshell关卡中的所有内容都终止,但在它之后继续执行(即被out打印)?

我试过的:

一种解决方案是使用kill 0(杀死当前进程组中的所有内容)来退出两个内部命令组,但这种echo "out"情况永远不会发生;整个小组都将被杀死,而不仅仅是外部子壳。

我也尝试过暂时覆盖然后unsetingexit函数,但这似乎只是将问题推到了另一个位置。也许我做错了;我绝不是 Bash 大师。

为什么?

在不深入细节的情况下,奇怪的 subshel​​l 连接的命令组是必要的,因为使用&fork out 进程在我的系统上无法确定地工作(嵌入式 *nix)。因此,管道连接的组确保如果do_first_thing运行时间过长(在上面的示例中为 10 秒),do_second_thing将会发生。实际用例要复杂得多,但这是问题的根源。

干杯!

4

2 回答 2

0

沿着这些思路的结构是否合适?

touch /tmp/sentinel-file
(do_first_thing; rm /tmp/sentinel-file) &
pid=$!
sleep 10
if [[ -r /tmp/sentinel-file ]]
then
  kill $pid
  rm /tmp/sentinel-file
  do_second_thing
fi

如果您运行此副本的多个副本,则会出现一些竞争条件,但在某些方面它可能比您现在所做的要干净一些。

于 2012-08-13T21:25:13.403 回答
0
#!/bin/bash                                                                     
(
  #outer subshell                                                                 
  {
    #inner command group, pipe-connected to ensure simultaneous invocation      
    first_step;
    ps -ef | grep './lol.bash' | awk '{print $2}' | xargs kill;
    #die, somehow                                                           
  } | {
    #inner command group, pipe-connected to ensure simultaneous invocation      
    ./lol.bash;
  }
)
echo "out"

并且 lol.bash 包含你的睡眠,然后是所谓的“second_step”......它不是很干净,但它会转动。

另一种方法是在第二部分创建一个循环,检查第一步是否完成,一段时间,然后离开,或者在第一步中清理所有东西,如果时间到了就做一些事情.. .

注意:显然你可以在每一步启动一个不同的进程,然后在你想要的时候杀死它......(你只需要知道 pid......)

于 2012-08-13T21:56:08.390 回答