带有2个函数的循环以'&'开头仍会顺序运行它们

时间:2018-08-23 19:16:22

标签: linux bash

脚本:

#!/bin/bash

done=
count=0

functionA { # MAIN
    sleep 30
    done=y
}

functionB() { #PROGRESS
    local A=${1:-30} #width
    local B=${2:-1} #count time 1s
    local C=${3:-"X"} #existing char
    local D=${4:-"*"} #override char
    local i

        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}
((counter++))
        done        
        echo
}

functionA 是我脚本主要工作的占位符。

选择

functionB 是一个盲目的进度指示器,因为它需要 functionA 来完成一个不可预测的不同时间,并且无法衡量进度。

因此,该想法是每10秒钟探测一次 functionA 是否仍处于活动状态(通过' done '标记),打印探测的结果,并完成后,也请停止 functionB 。循环:

while [[ -z "$done" ]]; do
    if [ "$counter" -eq 0 ]
        then
            echo "Started"
        else
            echo "Not yet finished..."
    fi
    functionB 10  &
    functionA $!
done
echo "Finished"

我希望这些A和B函数能够独立运行,这意味着 functionB 会在由的' $ done '控制的子外壳循环中继续重复运行功能A

但是,它仅运行一次,然后停止等待 functionA 完成工作,设置标记并退出。

如果我仅运行进度功能( functionB 10 ),它将按预期运行-填充10个字符的长度条后,下降到下一行,打印所有状态。但是,当两个功能都使用运行时。

我在做什么错? (请解释)。

1 个答案:

答案 0 :(得分:1)

我同意@Barmar的评论-必须等待的是进度条,所以这应该是循环的。这在我的测试中有效:

#!/bin/bash

set -u
    # warn on use of undeclared variables

functionA() { # MAIN
    sleep 25     # So you can see it die in the middle of a functionB inner loop
}

functionB() { #PROGRESS
    local A=${1:-30} #width           # Please rename these to be, e.g., "width" :)
    local B=${2:-1} #count time 1s
    local C=${3:-"X"} #existing char
    local D=${4:-"*"} #override char
    local i

    while true            # Wait forever - the script will kill us when it's done
    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}"
            # No need for a counter
        done
        echo
    done
}

functionB 10 &         # Start the progress bar - it will run until we say otherwise
progress_pid="$!"

functionA 

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