You can pass the definition of the array to the remote bash
like so (here assuming the login shell of the remote user is bash
):
DISKS_definition=$(typeset -p DISKS)
for i in "${HOSTS[@]}"; do
ssh "$i" "$DISKS_definition"'
for j in "${DISKS[@]}"; do
echo "$j"
done'
done
Or if using the here-document approach:
DISKS_definition=$(typeset -p DISKS)
for i in "${HOSTS[@]}"; do
ssh "$i" bash <<EOF
$DISKS_definition
for j in "\${DISKS[@]}"; do
echo "\$j"
done
EOF
done
If your ssh
client and server allow passing LC_*
variables, you could also do
DISKS_definition=$(typeset -p DISKS)
for i in "${HOSTS[@]}"; do
LC_DISKS=$DISKS_definition ssh "$i" bash <<'EOF'
eval "$LC_DISKS"
for j in "${DISKS[@]}"; do
echo "$j"
done
EOF
done
All is in the quoting that determines which of the local or remote shell does the expansions. Remember variables are expanded inside double quotes and here-documents where the delimiter is not quoted (note the <<'EOF'
in the last example that prevents expansions inside the here-document while in the earlier examples (with <<EOF
) we had to use backslashes for things that we don't want expanded by the local shell).
For arrays that contain non-ASCII data, you'll want to make sure that the locale's character set is the same on the local and remote machine, or at least avoid multi-byte character sets other than UTF-8.
bash-4.3$ locale charmap
ISO-8859-1
bash-4.3$ a=($'foo\xa3$(uname>&2)bar' baz)
bash-4.3$ a_definition=$(typeset -p a)
bash-4.3$ LC_ALL=zh_HK.big5hkscs bash -c "$a_definition"
Linux
By switching to a different character set, the content of $a_definition
took a different meaning (here causing the uname>&2
command to be executed).
do
missing in your remotefor
loop.do
in the 2ndfor
loop is present in the actual script. I would get asyntax error
if it wasn't. I must have missed it when I copied and pasted. I have added it to the script above.