Search code examples
shellunixscriptingzshshebang

ZSH loops only over first item of the array


#/bin/zsh
servers=('10.138.0.8' '10.138.0.91')

for srv in $servers; do
   echo "Checking health for " $srv
   echo "=========================================="
   echo mntr | nc $srv 2181 
done

when I execute, I don't get loop over 2nd value 10.138.0.91, as shown below

[devops@devops]~% ./healthcheck/zookeeper.sh  
Checking health for  10.138.0.8
==========================================
zk_version      3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
zk_avg_latency  0
zk_max_latency  0
zk_min_latency  0
zk_packets_received     9
zk_packets_sent 8
zk_num_alive_connections        1
zk_outstanding_requests 0
zk_server_state follower
zk_znode_count  4
zk_watch_count  0
zk_ephemerals_count     0
zk_approximate_data_size        27
zk_open_file_descriptor_count   28
zk_max_file_descriptor_count    4096

why?


Solution

  • Because your script isn't being executed by zsh. Fix the shebang line: #!/bin/zsh

    Why does your script get executed anyway, even without a shebang line? Because:

    1. The kernel doesn't recognize an executable format, and gives up (the execve system call returns ENOEXEC).
    2. The shell that tried to execute the file ./healthcheck/zookeeper.sh responds by opening the file and noticing that it looks like text that might be a script. Out of tradition, it calls /bin/sh to execute the script. For /bin/sh, the first line is just an ordinary comment.

    Apparently /bin/sh is bash or ksh on your machine. The array assignment works with the same syntax as zsh, but the reference to the array doesn't — in ksh/bash syntax, you'd have to write "${servers[@]}" (modeled after "$@") to enumerate the elements of an array.