Remix.run Logo
gorgoiler 2 days ago

The IFS part is misguided. If the author used double quotes around the array reference then words are kept intact:

  vs=("a b" "c d")
  for v in "${vs[@]}"
  do      #^♥      ♥^
    echo "$v"
  done
  #= a b
  #= c d
Whereas in their (counter-)example, with missing quotes:

  vs=("a b" "c d")
  for v in  ${vs[@]}
  do      #^!      !^
    echo "$v"
  done
  #= a
  #= b
  #= c
  #= d
To paraphrase the manual: Any element of an array may be referenced using ${name[subscript]}. If subscript is @ the word expands to all members of name. If the word is double-quoted, "${name[@]}" expands each element of name to a separate word.
degamad 2 days ago | parent [-]

The author addresses that in footnote 2:

    > [2] Another approach: instead of altering IFS, begin the loop with for arg in "$@" - double quoting the iteration variable. This changes loop semantics to produces the nicer behavior, and even handles a few edge cases better. The big problem is maintainability. It's easy for even experienced developers to forget to put in the double quotes. Even if the original author has managed to impeccably ingrain the habit, it's foolish to expect that all future maintainers will. In short, relying on quotes has a high risk of introducing subtle time-bomb bugs. Setting IFS renders this impossible.
gorgoiler 2 days ago | parent [-]

Thanks, I didn’t see that.

I still think the advice is misguided. Double-quote semantics are a fundamental and important part of getting shell scripting right. Trying to bend the default settings so that they are more forgiving of mistakes feels worse than simply fixing those mistakes.

In terms of maintainability, fiddling with IFS feels awkward. It’s definitely something you’ll need to teach to anyone unfamiliar with your code. Teach them how "" and @ work, instead!

(I agree about maintenance being hard. sh and execve() are a core part of the UNIX API but, as another comment here suggests, for anything complex and long-lived it’s important to get up to a higher level language as soon as you can.)