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