I'm contemplating to make all bash scripts of a large codebase shellcheck compliant, but the task is overwhelming, because too many developers have historically ignored rule number one of all shell scripting: always use quotes.
It would be helpful if there was a tool that could fix at least the quoting. I would then be able to fix the rest by hand. My regex didn't cut it, because only variables not already in a string must be quoted.
Sample input:
echo "Removing $a ${b} $(c $(c)) `d $d` ${10} $@ now"
rm -rf $a ${b} $(c $(c)) `d $d` ${10} $@
Sample output:
echo "Removing $a $b $(c "$(c)") `d "$d"` ${10} $@ now"
rm -rf "$a" "$b" "$(c "$(c)")" "$(d "$d")" "${10}" "$@"
It doesn't have to fix all the above, and it doesn't even have to be flawless (though that would be really nice), but it has to be right more often than not to be useful.
Here is my naïve regex that didn't cut it:
s:([^"])\$\{([_A-Za-z0-9]+)\}([^"]|$):\1"\$\2"\3:g
It transforms ${identifier} to "$identifier", except when immediately preceded or followed by a quote, but fails to detect if we are deeper within the string.
bash
parser to determine which parameter expansions are quoted and which are not. Regular expressions are not sufficient for such parsing. – Anisolebash
is not a regular language. – Pamphyliafiles="a b c"; touch ${files}; rm ${files}
is different fromfiles="a b c"; touch "${files}"; rm "${files}"
. – Lodging"$var1 $var2"
doesn't need to be replaced. It needs to be a program, an existing one (like shellcheck) or a new very simple one. It doesn't need to be a complete bash parser, because it will be totally focused in shell variables analysis. – Crepusculefiles=(a b c); touch -- "${files[@]}"; rm -f -- "${files[@]}"
. One of the cases for a code-review as that can't really be automated. – Humanize