0

I'm trying to set up a "check if machines are online" script with Bash, but running into an issue of when and where to define the variables so they're expanded properly. Something like:

#!/bin/bash
rm01="c01 c02 c03"
rm02="d01 d02 d03"
rm10="e11 e22 e33"
for room in rm01 rm02 rm03; do
    echo $room
    for computer in $room; do
        #run various nslookup/ping tests and report
    done
done
exit 0

I'm running into issues because I can't find a way to expand $room for its corresponding set of computers (in $rm01, $rm02, $rm10) listed at the beginning.

What am I doing wrong?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116

1 Answers1

1

The quick fix is to use variable indirection:

for computer in ${!room}; do

Relying on word splitting is rarely the best idea, though. You could use arrays and namerefs instead (requires Bash 4.3 or newer):

#!/usr/bin/env bash

# Declare arrays
rm01=(c01 c02 c03)
rm02=(d01 d02 d03)
rm03=(e11 e22 e33)

# Declare room as nameref
declare -n room

# Using nameref as control variable sets room as reference to each variable in turn
for room in rm{01..03}; do
    # Properly quoted array expansion
    for computer in "${room[@]}"; do
        echo "$computer"   # or whatever needs to be done
    done
done
exit 0
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
  • Is there a way to do the arrays/nameref method with older bash? I'm stuck on 3.4 because Apple updates its BSD binaries infrequently. The first example is working just fine, thanks. – phonedog365 Nov 22 '18 at 19:19
  • @phonedog365 You could install a more recent Bash with Homebrew; I think you're actually on Bash 3.2 with macOS. If you can't use namerefs, you can use indirection as in [this Q&A](https://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash). Another good read is [BashFAQ/006](https://mywiki.wooledge.org/BashFAQ/006). – Benjamin W. Nov 22 '18 at 19:31