【问题标题】:wget won't stop after the surrounding subshell is killedwget 不会在周围的 subshel​​l 被杀死后停止
【发布时间】:2016-08-29 10:26:42
【问题描述】:

见:

(wget http://stackoverflow.com/questions/ask && echo 'ok' || echo 'failed') & pid=$!
sleep 1      # this is curcial
kill $pid

如果取出第二行,脚本完成后不会挂wegt。 我想要实现的是在某个时间杀死wget进程(或整个子shell),并根据wget的退出代码做更多的处理。 你能向我解释为什么上面脚本中的 wget 没有被正确杀死,以及如何做到这一点?或者有什么方法可以实现我想要的?

【问题讨论】:

    标签: shell signals sh wget kill


    【解决方案1】:

    考虑以下几点:

    $ foo=foo
    $ export foo
    $ (foo=bar; echo foo is $foo); echo foo is $foo
    foo is bar
    foo is foo
    

    进程不会改变其父进程的环境。这也适用于 shell 进程和子 shell。

    大括号改变逻辑优先级而不创建子shell:

    $ foo=foo
    $ export foo
    $ { foo=bar; echo foo is $foo); }; echo foo is $foo
    foo is bar
    foo is bar
    

    所以我想你想要

    { wget http://stackoverflow.com/questions/ask \
      && echo 'ok' || echo 'failed'; } & 
    kill $!
    

    我想...杀死wget进程(或子shell)...并根据wget的退出代码进行更多处理。

    我假设这个例子被简化了,你真正想知道的是 wget 是否成功完成,以及它是否被杀死。所有这些信息都将在$! 中,除了echo 'failed' 将返回true。如果这是一个问题,请在回显消息之前捕获状态。

    【讨论】:

    • 谢谢,但是如果你把 sleep 1 放在 kill $! 之前它不起作用,我不想立即杀死 wget,而是在做一些工作之后。我认为在这种情况下,大括号和括号都会创建子shell,因为它们都在后台运行。
    【解决方案2】:

    不要执行kill $pid,而是执行以下操作:

    wpid=$(ps -o pid=,ppid=,cmd= \
            | awk '$2 == '$pid' && $3 == "wget" { print $1 }')
    [ -n "$wpid" ] && kill $wpid
    

    【讨论】:

      猜你喜欢
      • 2014-10-01
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      相关资源
      最近更新 更多