1

私の現在の使用例では、あるサーバーから 1 つ以上の他のサーバーにログ ファイルをコピーする scp スクリプトを作成しています。

いえ

server1:/my/path1/log-files.* --> log_server1:/log/path1/server1
server1:/my/path2/log-files.* --> log_server2:/log/path/server1
server1:/my/path3/log-files.* --> log_server1:/log/path2/server1

ログ ファイルの構成に bash (バージョン 4) で連想配列 (配列) を使用し、すべての A. 配列をループして、それらの名前をインデックス付き配列に入れたいと考えています。

しかし、変数を A. Array の名前として使用して、名前付きの A. Array を参照する方法に困惑しています。

例:

#!/bin/bash
# GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) from RedHat/CentOS 6.4
declare -A log_server1 log_server2
log_server1=([name]="ls1" [user]="user")
log_server2=([name]="ls2" [user]="user")

declare -A log1 log2 log3
log1=([log_server]="log_server1" [path]="/my/path1" [file]="log-files" [rpath]="/log/path1/server1")
log2=([log_server]="log_server2" [path]="/my/path2" [file]="log-files" [rpath]="/log/path/server1")
log3=([log_server]="log_server1" [path]="/my/path3" [file]="log-files" [rpath]="/log/path2/server1")

logs=(log1 log2 log3)

for log in ${logs[@]}
do
  # How can I now refer to the A. Array by the name of "log1", etc ?
  ...
done
4

2 に答える 2

3

間接展開を使用できますが、それは本当に醜いです!

#!/bin/bash

declare -A log_server1=([name]="ls1" [user]="user")
declare -A log_server2=([name]="ls2" [user]="user")

declare -A log1=([log_server]="log_server1" [path]="/my/path1" [file]="log-files" [rpath]="/log/path1/server1")
declare -A log2=([log_server]="log_server2" [path]="/my/path2" [file]="log-files" [rpath]="/log/path/server1")
declare -A log3=([log_server]="log_server1" [path]="/my/path3" [file]="log-files" [rpath]="/log/path2/server1")

logs=( log1 log2 log3 )

for log in "${logs[@]}"; do
    l_ls=$log[log_server]
    l_p=$log[path]
    l_f=$log[file]
    l_rp=$log[rpath]
    echo "array $log:"
    echo "    log_server => ${!l_ls}"
    echo "    path => ${!l_p}"
    echo "    file => ${!l_f}"
    echo "    rpath => ${!l_rp}"
done

上記でリンクしたリファレンス マニュアルのセクションでは、次の内容を確認できます。

パラメータの最初の文字が感嘆符 ( !) である場合、可変間接性のレベルが導入されます。Bash は、パラメーターの残りの部分から形成された変数の値を変数の名前として使用します。この変数は展開され、その値はパラメーター自体の値ではなく、残りの置換で使用されます。これは間接展開として知られています。これに対する例外は、以下で説明する${!prefix}およびの展開です。${!name[@]}インダイレクションを導入するために、感嘆符は左中括弧の直後に置く必要があります。

質問。log_server代わりに、連想配列、pathfilerpathキーlog1log2、で作成してみませんlog3か? 次のように:

#!/bin/bash

declare -A log_server1=([name]="ls1" [user]="user")
declare -A log_server2=([name]="ls2" [user]="user")

declare -A log_server path file rpath

log_server[log1]="log_server1"
path[log1]="/my/path1"
file[log1]="log-files"
rpath[log1]="/log/path1/server1"

log_server[log2]="log_server2"
path[log2]="/my/path2"
file[log2]="log-files"
rpath[log2]="/log/path/server1"

log_server[log3]="log_server3"
path[log3]="/my/path3"
file[log3]="log-files"
rpath[log3]="/log/path2/server1"

for log in "${!log_server[@]}"; do
    echo "log server $log:"
    echo "    log_server => ${log_server[$log]}"
    echo "    path => ${path[$log]}"
    echo "    file => ${file[$log]}"
    echo "    rpath => ${rpath[$log]}"
done
于 2013-12-01T15:29:41.407 に答える
0

私自身の答えを提示します。私はいくつかの健全な批判を期待しています:-) しかし、主な問題は、同一の連想配列をどのように使用し、統一された方法でそれらをループするかでした。

同じことを達成する方法についての提案は大歓迎です:

#!/bin/bash
# GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) from RedHat/CentOS 6.4
declare -A log_server1 log_server2
log_server1=([name]="ls1" [user]="user")
log_server2=([name]="ls2" [user]="user")

declare -A clog1 clog2 clog3
clog1=([log_server]="log_server1" [path]="/my/path1" [file]="log-files" [rpath]="/log/path1/server1/")
clog2=([log_server]="log_server2" [path]="/my/path2" [file]="log-files" [rpath]="/log/path/server1/")
clog3=([log_server]="log_server1" [path]="/my/path3" [file]="log-files" [rpath]="/log/path2/server1/")

for log in ${!clog*}
do
    l_ls=$log[log_server] ; l_p=$log[path] ; l_f=$log[file] ; l_rp=$log[rpath]
    l_ls=${!l_ls} ; l_p=${!l_p} ; l_f=${!l_f} ; l_rp=${!l_rp}
    r_n=$l_ls[name] ; r_u=$l_ls[user]
    r_n=${!r_n} ; r_u=${!r_u}
    echo "Array $log:"
    cmd="   scp ${l_p}/${l_f}* ${r_u}@${r_n}:${l_rp}"
    echo "${cmd}"
done

結果:

$./bash-A-Array.sh
Array clog1:
   scp /my/path1/log-files* user@ls1:/log/path1/server1/
Array clog2:
   scp /my/path2/log-files* user@ls2:/log/path/server1/
Array clog3:
   scp /my/path3/log-files* user@ls1:/log/path2/server1/
于 2013-12-01T17:35:41.017 に答える