<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged shellcheck</title>
<link>https://coderlegion.com/tag/shellcheck</link>
<description>Powered by Question2Answer</description>
<item>
<title>ShellCheck rates SC2086 as info. It let rm delete two files I never named.</title>
<link>https://coderlegion.com/28019/shellcheck-rates-sc2086-as-info-it-let-rm-delete-two-files-i-never-named</link>
<description>&lt;p&gt;SC2086 sits at info, ShellCheck's lowest default severity, and fires on every unquoted &lt;code&gt;$var&lt;/code&gt;, so it is usually the first rule anyone disables. I built the smallest test I could: a directory holding &lt;code&gt;quarterly&lt;/code&gt;, &lt;code&gt;report.txt&lt;/code&gt; and &lt;code&gt;quarterly report.txt&lt;/code&gt;, and a four-line script under &lt;code&gt;set -euo pipefail&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;report=&quot;quarterly report.txt&quot;
rm $report
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It deleted &lt;code&gt;quarterly&lt;/code&gt;. It deleted &lt;code&gt;report.txt&lt;/code&gt;. It left the one file it was asked to remove, and exited 0. rm was handed two names and both existed, so strict mode had nothing to catch.&lt;/p&gt;
&lt;p&gt;Bash expands the unquoted variable, splits the result on whitespace, globs any &lt;code&gt;*&lt;/code&gt; or &lt;code&gt;?&lt;/code&gt; against the current directory, and only then builds the argument list. &lt;code&gt;rm &quot;$report&quot;&lt;/code&gt; is one argument with no globbing, and it deletes the right file.&lt;/p&gt;
&lt;p&gt;The same bug hides in other shapes. &lt;code&gt;[ $name = &quot;root&quot; ]&lt;/code&gt; with an empty &lt;code&gt;$name&lt;/code&gt; gives &lt;code&gt;test&lt;/code&gt; two arguments: a complaint on stderr, a false condition, and the script keeps walking. &lt;code&gt;for f in $files&lt;/code&gt; is not flagged by ShellCheck 0.11.0 at all, and still breaks on the first name with a space.&lt;/p&gt;
&lt;p&gt;When you do want the split, such as a flag string read from a config, use an array or a one-line &lt;code&gt;# shellcheck disable=SC2086&lt;/code&gt; with the reason. A repo-wide &lt;code&gt;.shellcheckrc&lt;/code&gt; disable covers every future &lt;code&gt;rm&lt;/code&gt; as well. And &lt;code&gt;shellcheck --include=SC2086&lt;/code&gt; runs it alone as a CI gate.&lt;/p&gt;
&lt;p&gt;Every run, pasted from ShellCheck 0.11.0, is in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://bashsnippets.xyz/shellcheck/sc2086&quot;&gt;SC2086 deep dive on word splitting and globbing&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/28019/shellcheck-rates-sc2086-as-info-it-let-rm-delete-two-files-i-never-named</guid>
<pubDate>Tue, 29 Sep 2026 13:00:00 +0000</pubDate>
</item>
</channel>
</rss>