对于当前的用例,我正在创建一个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 (version 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发布于 2013-12-01 15:29:41
你可以使用间接膨胀,但它真的很难看!
#!/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、path、file和rpath来创建关联数组log1、log2和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-01 17:35:41
给出我自己的答案。我期待一些健康的批评:-)然而,主要问题是如何使用相同的关联数组,并以统一的方式遍历它们。
对如何实现这一目标的建议将不胜感激:
#!/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/https://stackoverflow.com/questions/20313425
复制相似问题