当FOR循环在周围时,kill“ $!”不起作用

时间:2018-08-28 10:21:02

标签: linux bash

如果涉及到FOR循环,看来 kill“ $!” 命令不起作用。

下面的脚本触发2个功能(主要和进度)同时运行。完成主体后,进度将被终止:

#!/bin/bash

functionA() { # MAIN
    sleep 15     
}

functionB() { #PROGRESS
    local A=${1:-30} 
    local B=${2:-1} 
    local C=${3:-"X"} 
    local D=${4:-"*"} 
    local i

    while true        
    do
        echo -en "["
        for i in $(seq 1 "$A")
        do
                echo -en "$C"
        done

        echo -en "]\0015["
        for i in $(seq 1 "$A")
        do
            echo -en "$D"
            sleep "${B}"
        done
        echo
    done
}

functionB 10 &         
progress_PID="$!"

functionA 

kill "$progress_PID"   # Stop the progress bar
echo "Finished"

效果很好。

但是,当我将它应该使用的真实代码放入 functionA 时,它包含一个 FOR 循环,进度永远不会结束,尽管主要功能早已完成:

functionA() {
        for IP in "${book[@]}"; do
                ssh user@"$IP" "sleep 15" > /dev/null 2>&1 &
        done
wait
}

我试图添加 echo“ $!” 来捕获“ $!”被抓得很好。是的,进程ID是恒定的,但是我在外壳中看不到它,因为它可能仅存在于子外壳中。

为什么尽管 progress_PID =“ $!” 尽管被抢走了却没有被杀死?

(请说明解决方法)

1 个答案:

答案 0 :(得分:3)

我怀疑您的wait也正在等待背景进度条。尝试捕获背景ssh实例的特定pid,然后专门等待它们:

functionA() {
        local a=()

        for IP in "${book[@]}"; do
                ssh user@"$IP" "sleep 15" > /dev/null 2>&1 &
                a+=($!)
        done

        wait "${a[@]}"
}

这会将背景ssh的PID放入数组中,然后等待数组的成员而不是“背景中的所有内容”,这是wait的默认行为。 bash手册页指出:

  

如果未指定n̲,则等待所有当前活动的子进程

注意:未经测试。可能含有坚果。