在bash和expect中,都有类似于map的数据结构,但用法有比较大差异。
bash中的map
bash中有两种数组:一种是索引数组(indexed array),也就是通过整数下标来索引数组,对应高级语言中的数组(array);另一种是关联数组(associative array),也就是通过任意字符串来查找元素,对应高级语言中的映射表(map或者hash map)。bash只支持一维数组,不过数组大小没有限制。注意索引数组的下标是从0开始的。另外,关联数组只在bash 4.0以上版本支持。
声明数组
声明一个索引数组:
1 2
| declare -a arr local -a arr
|
声明一个关联数组:
1 2
| declare -A map local -A map
|
数组的赋值和引用
索引数组
1 2
| arr=(var0 var1 var2 var3) echo ${arr[0]}
|
关联数组
1 2
| map=(["a"]="var1" ["bc"]="var2" ["def"]="var3") echo ${map["a"]}
|
数组的遍历
1 2 3 4 5 6
| declare -a arr arr=("a" "b" "c") echo "array length: "${#arr[@]} for k in ${!arr[@]}; do echo $k" = "${arr[$k]} done
|
1 2 3 4 5 6
| declare -A map map=(["a"]="hello" ["b"]="world" ["c"]="!") echo "map length: "${#map[@]} for m in ${!map[@]}; do echo $m" = "${map[$m]} done
|
expect中的map
expect是一种tcl
(Tool Control Language)语言,tcl
官网https://www.tcl.tk/。
array示例
1 2 3 4 5 6 7 8
| array set colors { red green blue } foreach name [array names colors] { puts "$name is $colors($name)" }
|
具体expect示例
批量进行ssh-copy-id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| array set arrays { ip1 password1 ip2 password2 ip3 password3 } foreach h [array names arrays] { set ip $h set passwd $arrays($h) spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $ip expect { "(yes/no)*" { send "yes\r"; exp_continue } "*assword*" { send "$passwd\r" } } }
|
另附一个expect示例
根据传进来的server参数,ssh到此server上进行rsync操作
1 2 3 4 5 6 7 8 9 10 11 12 13
| set timeout 1000 set server [lindex $argv 0] set user "user" set passwd "password" set cmd "export RSYNC_PASSWORD=password; rsync -avz /data/*/*2016-06-04-{14..23}.log data@172.31.10.10::data/rsync_history/" spawn ssh -l $user $server $cmd expect { "(yes/no)" { send "yes\r"; exp_continue } "*assword*" { send "$passwd\r" } } expect eof
|
参考
- Arrays In Bash: http://www.gnu.org/software/bash/manual/html_node/Arrays.html
- Array In TCL: http://wiki.tcl.tk/1032