0

I have the following script that I feel should loop through the contents of my file that it reads in, but for some reason it is exiting after the first iteration.

#!/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

Format of the hosts.txt file.

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

I feel like I am missing something silly. The thing is if I comment out the 2 lines where it is calling another script it loops just as I would expect. Calling the script is the problem?

ssbsts
  • 844
  • 1
  • 8
  • 13
  • 1
    Does `deploy_VM_PureFlex_Nstar.sh` use `ssh` or anything like that? It is probably reading the open fd and leaving it seeked to the end after the first loop. Try redirecting standard input from `/dev/null` for those calls or using a different fd for the `read` loop. (Also you can use `while IFS=$IFS, read -r name ip vlan image; do` to avoid adding `,` to `IFS` for the entire script.) – Etan Reisner Jun 10 '15 at 16:31
  • Yes, the deploy script that I am calling does use ssh to connect to a remote machine. I feel like that must be the problem, or something related to that script call, because as mentioned, simply commenting the 2 calls to the script results in the my main script executing normally and looping through all entries. – ssbsts Jun 10 '15 at 16:58
  • @EtanReisner, when you say "Try redirecting standard input from /dev/null for those calls", you just mean when I call the deploy script to try something like ">> /path/to/log 2>&1"? Sorry for if I misunderstood. I did try the redirect I just mentioned and it did not work, so wanted to see if you could clarify. Thanks for your comment. – ssbsts Jun 10 '15 at 17:16
  • Just for those calls yes, but those redirections are both *output*. You need to redirect input (e.g. `< /dev/null`). See the linked ticket. Also the `-n` option to `ssh`. – Etan Reisner Jun 10 '15 at 17:17
  • @EtanReisner adding the -n switch solved the issue. – ssbsts Jun 10 '15 at 19:10

1 Answers1

0

Your hosts.txt file is not POSIX compliant and contains no newline at the end of the file. You would need:

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

in order to read the final line. See Why should files end with a newline?

Community
  • 1
  • 1
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • thanks for the comment, but actually it seems your suggestion is not applicable. Perhaps i should make it POSIX compliant, but after the suggestion above by @EtanReisner the script is working and includes all my values in hosts.txt file. – ssbsts Jun 10 '15 at 19:35
  • Keep this in your hip pocket. 99% of the time if you are not reading the last line, it is due to the non POSIX line end (or missing line end is more correct). By testing whether the last variable in your `read` was filed, you can obtain the last line values. – David C. Rankin Jun 10 '15 at 22:50
  • Indeed. This was a very good suggestion and not one that I would have readily thought of. With just two lines this is trickier to notice also. The "all but last" symptom makes this easier to spot. – Etan Reisner Jun 11 '15 at 13:41