Search code examples
bashshellzsh

Do `sort` and `ls` return array? If not, why can we iterate without having to ${x[@]}


I have just noticed that I can write:

for i in $(sort $path); do
  echo $i
done

And it prints out perfectly fine. But when it comes to array:

arr=(i am array)

for i in $arr; do
  echo $i
done

# output (bash)
i

# outpus (zsh)
i
am
array

So I have to expand the array with:

for i in ${arr[@]}; do
  echo $i
done

#output (bash)
i
am
array

I suspect that sort and ls return just plain string with space and for statement just loops with space as a delimiter, am I wrong?. So should I use string with space to loop instead of an array?

I don't know technical term much, sorry for confusing question.

Thank you in advance.


Solution

  • From the bash man page:

        for name [ [ in [ word ... ] ] ; ] do list ; done
              The list of words following in is expanded, generating a list of
              items. <...>
    

    So when you write for i in ${arr[@]} or for i in $(sort $path), the shell substitutes the list in place of the expansion, and for iterates over items in that list that are delimited by the first character of IFS which is an special variable that defaults to a whitespace.

    Therefore, you are partially right: for does loop with a space as a delimiter, but neither sort nor ls return a space-delimited string. For that matter, run ls | xxd to see a binary dump of the output - the filenames from your directory are delimited by 0x0a which is ASCII for newline.