如何遍历 zsh 数组并在其他命令中使用索引和值?

How can I loop over zsh array and use index and value in other commands?

$ zsh --version
zsh 5.8 (x86_64-apple-darwin19.6.0)
$ tmux -V
tmux 3.2a

我正在通过 zsh 脚本在 tmux 中自动化远程服务器监控仪表板。

  1. 将命令的多行输出存储为 zsh 中的数组:(WORKS)
$ server_name_array=( $( aws ec2 describe-instances... ) )
$ declare -p server_name_array
typeset -a server_name_array=( name1 name2 name3 )
  1. 然后想在我的 tmux 命令中同时使用每个数组项的索引和值:(不起作用)
$ for i in "${!server_name_array[@]}"; \
do \
  tmux send-keys -t '=server:=servers.<server_name_index>' 'ssh <server_name_value> -t "<my-remote-command>"'; \
done;

但是我收到以下错误:

zsh: event not found: server_name_array[@]

我有 read 这是由于 bash 中的特殊 ! 运算符,并尝试按照建议转义/取消设置它但无济于事:

$ set +H
$ for index in "${"'!'"server_name_array[@]}"; do echo $index; done;
zsh: bad substitution
$ for index in "${"\!"server_name_array[@]}"; do echo $index; done;
zsh: bad substitution
$ for index in "${"'!'"server_name_array[@]}"; do echo $index; done;
zsh: bad substitution
$ for index in "${"\!"server_name_array[@]}"; do echo $index; done;
zsh: bad substitution
$ for index in "${!server_name_array[@]}"; do echo $index; done;
zsh: event not found: server_name_array[@]
$ for index in "${\!server_name_array[@]}"; do echo $index; done;
zsh: bad substitution

我做错了什么?

更新:

这是我通过 .sh 文件调用的脚本:

$ ls -ahl /usr/local/bin/server_mon
lrwxr-xr-x  1 <user>  admin    48B <date> /usr/local/bin/server_mon -> ~/scripts/server_mon.sh
#!/bin/sh

set -euC

cd <project-directory>

# our main function
attach() {
    [ -n "${TMUX:-}" ] &&
        tmux switch-client -t '=server' ||
        tmux attach-session -t '=server'
}

# attach to server if it already exists
if tmux has-session -t '=server' 2> /dev/null; then
    attach
    exit 0
fi

# start a named session called server
tmux new-session -d -s 'server' -n 'local'; \

# new tmux servers window
tmux new-window -d -t '=server' -n 'servers'; \

# store the names of our server instances in an array
server_name_array=( $( aws ec2 describe-instances ... ) )
declare -p server_name_array
# typeset -a server_name_array=( name1 name2 name3 )
server_name_array_length=${#server_name_array[@]:1}

# create split panes for number of servers (n-1)
for i in "${server_name_array[@]:1}"; do tmux split-window -t '=server:=servers' -d; done;
# select an even vertical layout
tmux select-layout -t '=server:=servers' even-vertical;

# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# HERE IS WHAT I AM TRYING TO DO
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

# Loop over ZSH array of server names, and send ssh commands containing server names to panes via the array index
for i in "${!server_name_array[@]}"; 
do
    # tmux send-keys -t '=server:=servers.<server_name_index>' 'ssh <server_name_value> -t "<my-remote-command>"';
    tmux send-keys -t '=server:=servers.${$i}' 'ssh ${server_name_array[$i] -t "sudo su;"' Enter; 
done;

以下脚本在 bash 和 zsh 中产生相同的结果:

declare -a server_name_array=(a b c)

test "$ZSH_VERSION" && c=1 || c=0

for ((i=0; i<${#server_name_array[@]}; i++)); do
    echo $i "${server_name_array[i+c]}"
done

输出:

$ bash test.sh
0 a
1 b
2 c
$ zsh  test.sh
0 a
1 b
2 c