While tracking down an error in my shellscript, I found the following behavior in this code snippet:
declare -a filelist
readarray filelist < <(ls -A)
readonly filelist
for file in "${filelist[@]}"; do
sha256sum ${filelist[$file]} | head -c 64
done
When the array filelist
is not in double quotes, the command succeeds. I've been using ShellCheck to try to improve my coding, which recommends-
Double quote to prevent globbing and word splitting.
I'm not worried about word splitting in this case, but in a lot of other cases I am, so I'm trying to keep my code consistent. However, when I double quote the array, the command fails. Simplifying the code to a single element gives the following:
bash-5.0# sha256sum ${filelist[0]} | head -c 64
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
bash-5.0# sha256sum "${filelist[0]}" | head -c 64
sha256sum: can't open 'file1
': No such file or directory
I can obviously just... not double quote because in this instance word splitting isn't a concern. But I wanted to post because in the future it might be.
My question has two parts:
- Is there a "best-practices" way to prevent word splitting other than double quoting the array as above?
Where are the single quotes coming from in the array?Edit: there are no single quotes. The single quotes are the error showing the name of the file that cannot be opened.
Also, just out of curiosity, why does echo ${filelist[0]}
not contain an additional newline but echo "${filelist[0]}"
does?
echo foo
will output a newline.echo -n foo
will not.