有谁能解释一下为什么 pid 没有从我的 pid 列表中删除吗?每次我进入这个循环时,for循环仍然发生相同的次数。var i等于pid的数量。所以循环 while 应该在所有 pid 完成时停止,但它没有!我在 pids 数组中仍然有 pid
这个命令似乎不起作用: pids=("${pids[@]/$pid}") 有什么问题吗?我想从 pids 数组中删除 $pid 。
while [ $i != 0 ]
do
for pid in "${pids[@]}"
do
if [ -z "$(ps -p $pid -o pid=)" ]
then
echo "i = $i ,pid $pid is finished" | tee -a $LOGFILE
((i--))
pids=("${pids[@]/$pid}")
echo
else
echo "i = $i ,pid $pid is not finished"
fi
done
sleep 4
clear
done
答案1
问题是,当您这样做时("${pids[@]/$pid}")
,它会$pid
用空字符串(“”)替换数组中的项目。所以该项目实际上并不是已删除从数组中,它只是被取代带有空字符串项。
我猜测在一些 pid 从数组中“删除”后,下一个周期for pid in "${pids[@]}"
,以下行将产生错误,因为至少一些的 $pid 变量将为空:
if [ -z "$(ps -p $pid -o pid=)" ]
这ps
可能会向 stderr 抛出一些错误,但命令的输出 (STDOUT) 将为空,因此它将减$i
1,最终$i
可能会降至零以下,并且由于它永远不会为 0,因此循环永远不会停止。
由于数组中的所有项目都是数字,因此您可以通过删除以下行中的引号来解决此问题:
pids=("${pids[@]/$pid}")
因此,它会是:
pids=(${pids[@]/$pid})
如果没有引号,空元素将从数组中删除。
这是一个简短的例子:
$ array=( 1 2 3 )
$ echo "${array[@]/1}"
2 3
# Notice that the first item is replaced with an empty string
$ echo ${array[@]/1}
2 3
# Without the quotes, the empty string is removed
请注意,这只有效,因为数组中的项目是数字。如果数组包含字符串和空格,它将不起作用。
另外,该方法仅替代子串(不一定是整个数组项),因此,例如,如果pids=( "1", "123" )
、 和pid=1
,则 的结果(${pids[@]/1})
将是( "23" )
(从“123”中删除“1”,仅保留“23”。
请参阅以下内容回答了解更多详细信息以及从任何数组中删除项目的方法,无论数组的内容如何。
免责声明:
这个答案仅解释了为什么您的脚本没有按预期工作。我的建议可能会让你的脚本工作,但它并不是以最优化的方式编写的。有许多更改可以使脚本更清晰、更高效,但我不会在这个答案中深入讨论。