Bash - SSH経由でリモートホストにアレイを渡す

Bash - SSH経由でリモートホストにアレイを渡す

smartctl複数のリモートホストにログインし、(パッケージ内の)配列で定義されたディスクで実行されるBashスクリプトを作成しました。配列はリモートホストに渡すことができますが、スクリプトは最初の要素を繰り返し繰り返し表示します。配列を文字列として扱い、最初の要素以降のすべての要素を無視するようです。smartmontoolsDISKS

DISKS=("/dev/sda" "/dev/sdb" "/dev/sdc")
HOSTS=("Ariadne" "Nyx")

for i in "${HOSTS[@]}"; do
    ssh "$i" "bash" << EOF
        for j in "${DISKS[@]}"; do
            echo "$j"
        done
EOF
done

リモートホストで(2番目のforループの前に)配列を定義しようとしましたが、DISKS=("${DISKS[@]}")役に立ちませんでした。

SSHを介してアレイをリモートホストに正しく渡し、アレイを繰り返すにはどうすればよいですか?

ベストアンサー1

次のように配列の定義をリモートで渡すことができますbash(これはリモートユーザーのログインシェルがあると仮定しますbash)。

DISKS_definition=$(typeset -p DISKS)
for i in "${HOSTS[@]}"; do
  ssh "$i" "$DISKS_definition"'
    for j in "${DISKS[@]}"; do
      echo "$j"
    done'
done

またはここで説明されている方法を使用する場合:

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

sshクライアントとサーバーが変数の受け渡しを許可している場合は、LC_*この操作も実行できます。

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

参照のすべての内容は、拡張を実行するローカルまたはリモートシェルを決定します。変数は二重引用符内で拡張され、ここでは区切り文字が引用符で囲まれていない文書<<'EOF'で拡張される<<EOFことに注意してください。ローカルシェルによって拡張されます)。

非ASCIIデータを含む配列の場合、ローカルおよびリモートシステムのロケールの文字セットが同じであることを確認するか、少なくとも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

別の文字セットに切り替えると、内容の$a_definition意味が異なります(ここでuname>&2コマンドが実行されます)。

おすすめ記事