2015-06-10 100 views
0

我有以下脚本,我觉得应该循环读取文件的内容,但由于某种原因它在第一次迭代后退出。Bash脚本没有按预期循环

#!/usr/bin/bash 

    scriptDir=/soft/automation/scripts 

    cd $scriptDir 

    #LOOP THROUGH THE LIST OF HOSTS AND TEARDOWN/REBUILD EACH 
    IFS=$IFS, 
    while read -r name ip vlan image; do 
    echo "$(date) : Beginning teardown of host ${name}_${vlan}..." 
    echo "$(date) : Executing command: ./deploy_VM_PureFlex_Nstar.sh -d -n ${name}_${vlan}" 
    ./deploy_VM_PureFlex_Nstar.sh -d -n ${name}_${vlan} 
    exitCode=$? 
    if [[ $exitCode -eq 0 ]]; then 
    echo "$(date) : Teardown of host ${name}_${vlan} completed successfully (exit code: $exitCode). Sleeping for 60 seconds..." 
    else 
    echo "$(date) : Teardown of host ${name}_${vlan} completed with errors (exit code: $exitCode). Sleeping for 60 seconds..." 
    fi 
    sleep 60 
    echo "$(date) : Beginning rebuild of vm for host $name" 
    echo "$(date) : Executing command: ./deploy_VM_PureFlex_Nstar.sh -a -n ${name} -i ${ip} -v ${vlan} -r ${image} -p normal" 
    ./deploy_VM_PureFlex_Nstar.sh -a -n ${name} -i ${ip} -v ${vlan} -r ${image} -p normal 
    exitCode=$? 
    if [[ $exitCode -eq 0 ]]; then 
    echo "$(date) : Rebuild of vm for host ${name}_${vlan} completed successfully (exit code: $exitCode). Sleeping for 60 seconds..." 
    else 
    echo "$(date) : Rebuild of vm for host ${name}_${vlan} completed with errors (exit code: $exitCode). Sleeping for 60 seconds..." 
    fi 
    sleep 60 
    done < ${scriptDir}/hosts.txt 

hosts.txt文件的格式。

host01,192.168.1.1,5,BaseImg_DB_20150528 
host02,192.168.1.2,5,BaseImg_APP_20150528 

我觉得我失去了一些愚蠢的东西。事情是,如果我注释掉它所调用的另一个脚本的2行,就像我期望的那样循环。调用脚本是问题所在?

+1

'deploy_VM_PureFlex_Nstar.sh'是否使用'ssh'或类似的东西?它可能读取了开放的fd,并在第一个循环之后将其搜索到最后。尝试将'/ dev/null'的标准输入重定向到这些调用,或对'read'循环使用不同的fd。 (也可以使用'while IFS = $ IFS,读取-r name ip vlan image; do'以避免为整个脚本添加','到'IFS'。) –

+0

是的,我调用的部署脚本确实使用SSH连接到远程机器。我觉得这肯定是问题,或者是与脚本调用有关的东西,因为如前所述,简单地对脚本进行2次调用会导致我的主脚本正常执行,并循环遍历所有条目。 – ssbsts

+0

@EtanReisner,当你说“尝试从/ dev/null对这些调用重定向标准输入”时,你只是指当我调用部署脚本来尝试诸如“>>/path/to/log 2>&1”之类的东西时?对不起,如果我误解了。我确实尝试了刚刚提到的重定向,但它不起作用,所以想看看你能否澄清。谢谢你的评论。 – ssbsts

回答

0

您的hosts.txt文件不符合POSIX标准,并且在文件结尾处不包含newline。您需要:

while read -r name ip vlan image || [ -n "$image" ]; do 

为了读取最后一行。请参阅Why should files end with a newline?

+0

感谢您的评论,但实际上,您的建议似乎并不适用。也许我应该让它符合POSIX标准,但在上面的@EtanReisner建议之后,脚本正在工作,并将所有值包含在hosts.txt文件中。 – ssbsts

+0

把它放在你的臀袋里。 99%的时间,如果你不读最后一行,这是由于非POSIX行结束(或缺少行结束更正确)。通过测试'read'中是否存在最后一个变量,您可以获取最后一行值。 –

+0

确实。这是一个很好的建议,而不是我想到的。只需两条线就可以知道。 “除了最后一个”症状使得这更容易被发现。 –