I try to run a command for a list of hosts and then store the output in a variable in a loop. I also created an array to associate ip/hostname as my command will only accept IP address as an argument but I want to use hostname and channel name in variable name. My code looks something like:
#!/bin/bash
IP="10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5"
CHANNEL="1 2 3 "
USERNAME="username"
SCRIPT_HOST="myscript_host"
HOME_DIR="/home/myuser"
SCRIPT_DIR=$HOME_DIR/scripts
COMMAND="sudo /path_to_my_remote_script"
SSH="ssh -t -o ConnectTimeout=10 -l $USERNAME"
declare -A array
array[10.0.0.1]="host1"
array[10.0.0.2]="host2"
array[10.0.0.3]="host3"
array[10.0.0.4]="host4"
array[10.0.0.5]="host5"
for ip in ${IP} ; do
for channel in ${CHANNEL} ; do
my_variable_name_$(${array[$($ip)]})_$c=$($SSH "$COMMAND -i $ip |grep -i \"ipv4 count\"|awk {print \$4}'")
echo my_variable_name_$(${array[$($ip)]})_$c
done;done
When I execute my script I receive an error message like:
./test_array.sh: line 20: 10.0.0.1: command not found ./test_array.sh: line 20: array: bad array subscript
I can guess it's a syntax error but can't figure out. I appreciate any help.
I'd rewrite that as
declare -A array
array[10.0.0.1]="host1"
array[10.0.0.2]="host2"
array[10.0.0.3]="host3"
array[10.0.0.4]="host4"
array[10.0.0.5]="host5"
channels="1 2 3"
script=/path_to_my_remote_script
cmd=(ssh -t -o ConnectTimeout=10 -l username myscript_host)
for ip in "${!array[@]}" ; do
for channel in $channels ; do
varname=my_variable_name_${array[$ip]}_$channel
echo $varname
remote_script="sudo $script -i $ip | awk -v IGNORECASE=1 '/ipv4 count/ {print \$4}'"
out=$( "${cmd[@]}" "$remote_script" )
declare "$varname=$out"
done
done
declare
command can assign to dynamically created variable names without having to use eval awk
, you don't need to use grep
first On second thought, I'd use another array to store the output, using a pseudo-multi-dimensional key:
declare -A my_variable_name
for ip in "${!array[@]}" ; do
for channel in $channels ; do
remote_script="sudo $script -i $ip | awk -v IGNORECASE=1 '/ipv4 count/ {print \$4}'"
my_variable_name[$ip,$channel]=$( "${cmd[@]}" "$remote_script" )
done
done
In this line
my_variable_name_$(${array[$($ip)]})_$c= ...
the $(${array{...}})
syntax is the issue. Essentially the $(...)
wrapping the array is trying to call a command. Remove the $(
and corresponding )
. Likewise in the echo
statement below that.
You have to run this through eval
and to avoid complicated/unreadable statements I would use a temporary variable:
vname=my_variable_name_${array[$ip]}_$c
tmp=$($SSH ...)
eval $vname=\$tmp
To see what's going on, you can add a
set -x
before the statements or call it as bash -x your-script
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.