In bash, I would like to transform a PATH-like environment variable that may contain space-separated elements into an array
, making sure eleme
# Right. Add -d '' if PATH members may contain newlines.
IFS=: read -ra myPath <<<"$PATH"
# Wrong!
IFS=: myPath=($PATH)
# Wrong!
IFS=:
for x in $PATH; do ...
# How to do it wrong right...
# Works around some but not all word split problems
# For portability, some extra wrappers are needed and it's even harder.
function stupidSplit {
if [[ -z $3 ]]; then
return 1
elif [[ $- != *f* ]]; then
trap 'trap RETURN; set +f' RETURN
set -f
fi
IFS=$3 command eval "${1}=(\$${2})"
}
function main {
typeset -a myPath
if ! stupidSplit myPath PATH :; then
echo "Don't pass stupid stuff to stupidSplit" >&2
return 1
fi
}
main
Rule #1: Don't cram a compound data structure into a string or stream unless there's no alternative. PATH
is one case where you have to deal with it.
Rule #2: Avoid word / field splitting at all costs. There are almost no legitimate reasons to apply word splitting on the value of a parameter in non-minimalist shells such as Bash. Almost all beginner pitfalls can be avoided by just never word splitting with IFS. Always quote.