Bash:当条件X满足时如何继续for循环

问题描述 投票:0回答:1

我正在尝试使用 GitHub Actions 在多个虚拟机上启动一个进程。但是,该命令未完成(因为它需要继续运行),因此我的 for 循环有点挂起。

我需要的是一种检查命令的日志输出(位于已知文件中)的方法,然后每当日志文件中出现特定句子时继续循环。

这是我目前拥有的一个最小示例:

#! /bin/bash

VMS=("10.10.789.001" "10.10.789.002" "10.10.789.003")
for VM in "${!VMS[@]}"; do
command.sh "$VM"
done

命令.sh:

#! /bin/bash
vmip=$1
ssh user@"$vmip" -T "myprogram -flag &> output.log"

这在某种意义上是有效的,即建立连接,启动

myprogram
并将其输出重定向到
output.log
。但是,由于
myprogram
继续运行(按预期),因此
for
循环永远不会到达
done

我尝试过像这样设置

timeout

#! /bin/bash

VMS=("10.10.789.001" "10.10.789.002" "10.10.789.003")
for VM in "${!VMS[@]}"; do
timeout 5m command.sh "$VM"
done

然而,这结束了整个脚本,因为它在达到超时后有效地抛出了

exit
,并且仍然不会继续
for
循环。

我知道

myprogram
会将
setup complete
写入
output.log
文件,因此我可以通过执行以下操作来检查:

#! /bin/bash
cat vault.log | grep "setup complete"
if [ $? = 0 ]; then
<do something>
fi

如果满足上述条件,则程序已完成设置,现在正在运行,这就是我想要的。但是,我不知道

<do something>
部分需要做什么,以确保原始
for
循环能够继续。

注意我无权访问

myprogram
程序的内容。这只是我需要运行的现有程序,而不是我自己可以改变的东西。

bash shell
1个回答
1
投票

后台处理启动

ssh
的每个
myprogram
命令。然后执行某种循环来检查日志。

命令.sh:

#! /bin/bash

main()
{
    local ip="$1"

    # Run the program in the background and redirect output to the log file
    ssh user@"$ip" -T "myprogram -flag &> output.log" &
    local ssh_pid=$!

    local max_iterations=100
    local iter_sleep_seconds=2


    # Wait until the setup complete message appears in the log file
    for ((i=1; i<=max_iterations; i++))
    do
        if ssh user@"$ip" -T "grep 'setup complete' output.log"
        then
            echo "Setup complete on $ip."
            break
        else
            echo "Waiting for setup to complete on $ip..."
            sleep $iter_sleep_seconds
        fi
    done

    if (( i > max_iterations ))
    then
        echo "Maximum number of iterations reached for $ip. Killing the instance."
        kill $ssh_pid
        return 1
    fi

    return 0
}

main "$@"

后台处理

command.sh

的每次调用

main.sh:

VMS=("10.10.789.001" "10.10.789.002" "10.10.789.003")

for VM in "${VMS[@]}"
do
    ./command.sh "$VM" &
done

wait
echo "All VM processes are done. Check log above if successful."
© www.soinside.com 2019 - 2024. All rights reserved.