$ zsh --version
zsh 5.8 (x86_64-apple-darwin19.6.0)
$ tmux -V
tmux 3.2a
I am automating a remote server monitoring dashboard in tmux via zsh script.
- Store the multiline output of a command as an array in zsh: (WORKS)
$ server_name_array=( $( aws ec2 describe-instances... ) )
$ declare -p server_name_array
typeset -a server_name_array=( name1 name2 name3 )
- Then want to use both the index and value of each array item in my tmux command: (DOES NOT WORK)
$ 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;
But I get the following error:
zsh: event not found: server_name_array[@]
I have read this is due to the special ! operator in bash and have tried escaping / unsetting it as suggested to no avail:
$ 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
What am I doing wrong?
UPDATE:
Here is my script invoked via .sh file:
$ 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;
#!/bin/shat the top. I'm using zshell in terminal. Testing these command I am using the terminal. When I run the script aliased to <script.sh>, is ZSH running it or BASH?#!/bin/shshebang, you shouldn't use any non-POSIX features (like arrays) at all, because you aren't in control of which shell the scripts runs under. Do not worry about figuring out what /bin/sh is on your system, because that's subject to change. If you want to use non-POSIX features, you should pick a specific shell, use a shebang that specifies that shell, and then use that shell's syntax.