I just wanted to confirm here since I've only tested in dash shell, but do loop variables collide with variables in the outer scope in shell scripts in general? For example
#! /bin/sh
i='1 2 3'
a='a b c'
for i in $a; do
echo "$i"
done
echo "$i"
This outputs:
a
b
c
c
which makes sense to me. That is, it seems to indicate that I'm right that loop variables will collide (they share the same namespace as the outer scope). I want to know because if I'm using an older-style shell that doesn't have the local command, I want to be sure to unset loop variables I use in functions. The texts I've read cover unset, but don't seem to cover this case.
Am I right?
for i in $ais itself an antipattern. The correct way to store lists of things is with an array-type variable. That is,a=( a b c ), thenfor i in "${a[@]}"; that way you can iterate over lists of strings even when those individual strings can contain spaces or be interpreted as globs.a='Hello[world] Goodbye'-- if there's a file namedHellooorHellodin the directory where the script is run, those filenames would be substituted into$iinstead of the literalHello[world]string. Whereasa=( 'Hello[world]' 'Goodbye' )andfor i in "${a[@]}"will assign exactlyHello[world]no matter what filenames exist.