我有一个Bash函数,它执行一系列命令,这些命令应该按照我所看到的顺序执行。我需要它们等待上一个命令完成,但由于某种原因,它们通常不按顺序执行。脚本看起来像这样:
func() {
echo "Executing command 1"
"$myPath/bin/command1" "$1" "ARG"
folderName="$dateStr"
echo "Executing command 2"
"$myPath/bin/command2" "$1" "$folderName"
"$myPath/bin/command3" "$1"
if [ "ignore" == "true" ]; then
"$myPath/bin/command4" -i "$i"
else
"$myPath/bin/command4" "$1"
fi
}
由于某种原因超出了我,在调用此函数时,我始终按顺序执行命令1到3,除了命令4在1和2之间执行!我没有在后台放置任何进程,因此不应该并行执行任何操作。然而,这似乎确实是以某种方式发生的事情。
我尝试插入一些wait
命令以查看它们是否因某些原因有所帮助,但它们似乎没有任何效果。我不确定提供什么其他信息,因为这看起来很简单,因此我为何感到困惑。这些命令是相当长的脚本,所以除非它们的内容变得相关,否则我不会包含它们。
我的操作系统是Debian 7(Wheezy),Bash版本是4.2.37。
以下是其中一个命令的示例,它们通常具有相似的行为。这个恰好相当短。指令代码3:
#!/bin/bash
mypath=~/"pathToDirectory"
source "$mypath/bin/config"
func() {
echo "Setting time at ${SiteName[$1]} at ${SiteIP[$1]}"
str="TIME $(date -u -d '7 hours ago' "+%m/%d/%Y,%H:%M:%S")"
bash "$mypath/bin/someCommand" "${SiteName[$1]}" "$str"
}
if [ "$#" == "0" ]; then
for ((i=0;i<=SiteIndex;i++)); do
if [ "${SiteType[$i]}" == "Type" ]; then
func "$i" &
fi
done
else
for ((i=0;i<=SiteIndex;i++)); do
if [ "${SiteName[$i]}" == "$1" ]; then
chosenSiteNo="$i"
break
fi
done
if [ -z "$chosenSiteNo" ]; then
echo "Unrecognized site name. Cannot set time."
exit 1
fi
func "$chosenSiteNo"
fi
wait
echo "Done."
我发现了这个难题的关键部分。这就是我在主脚本中调用func()
的方式。我这样做了:
for ((i=0;i<=SiteIndex;i++)); do
if [ ...conditions... ]; then
func "$i" &
fi
done
对六个“网站”并行运行func()
六次,但我忘了command3
和command4
都是遍历每个“网站”的循环。问题不是执行的顺序,而是我有一个循环循环的事实,所以当func()
的一个实例在其余部分之前完成时,它为所有人执行了command3
和command4
其他'网站在他们自己的command2
中完成func()
之前的网站!
......现在我觉得自己有点像白痴......
我认为,在这里学到的经验是,当我不情愿地使用for
循环时,我必须小心!
另外:使用set -x
或/bin/bash -x
是一个非常好的技巧!我必须记住这一点!