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.