如果涉及到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 =“ $!” 尽管被抢走了却没有被杀死?
(请说明解决方法)
答案 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̲,则等待所有当前活动的子进程
注意:未经测试。可能含有坚果。