So, technically I learned this yesterday but 🤷♀️
As part of our CI/CD testing, we run shellcheck against our shell scripts, and saw the following: -
^----^ SC2086 (info): Double quote to prevent globbing and word splitting.
for a piece of code that referenced a variable e.g. : -
echo $FILES
The shellcheck Wiki covers this: -
and suggests that $FILES be wrapped in double quotes e.g. : -
echo "$FILES"
So far, so good
However, the code in question was actually a variable containing more than one element e.g. : -
FILES="a.txt b.txt c.txt"
so the next line in the script which leveraged the values within the $FILES variable: -
ls "$FILES"
fails with: -
ls: a.txt b.txt c.txt: No such file or directory
Thinking more about this, this kinda made sense i.e. we're treating the values within the $FILES variable as elements within an array, but we're not actually treating the variable as an array, by incrementing through the elements by an index.
The Wiki does reference this: -
Using that as inspiration, I updated the script: -
ls "${files[@]}"
In essence, this is creating a "real" array from the $FILES variable, and then we're incrementing the index using [@]
To be clear, I also took inspiration from: -
How to be explicit about intentional word splitting?
and this is my demo / test script: -
# Set variable
FILES="a.txt b.txt c.txt"
echo "Works, but breaks shellcheck"
ls $FILES
echo "Fails, but passes shellcheck"
ls "$FILES"
echo "Works, and passes shellcheck"
read -ra files <<<"${FILES}"
ls "${files[@]}"
which, when I run it, does this: -
./test-sc.sh
Works, but breaks shellcheck
a.txt b.txt c.txt
Fails, but passes shellcheck
ls: a.txt b.txt c.txt: No such file or directory
Works, and passes shellcheck
a.txt b.txt c.txt
Finally, for now, there's a great shellcheck plugin for VS Code: -
ShellCheck for Visual Studio Code
and, for the record, the shellcheck project is available on GitHub
No comments:
Post a Comment