koalaman / shellcheck

ShellCheck, a static analysis tool for shell scripts
https://www.shellcheck.net
GNU General Public License v3.0
36.31k stars 1.77k forks source link

SC2034 misses variables exported with allexport/set -a #2331

Open brchrisman opened 3 years ago

brchrisman commented 3 years ago

For bugs

For new checks and feature suggestions

Here's a snippet or screenshot that shows the problem:


[bchrisman (team/business_ps): scale-product] $ cat /tmp/a
#!/bin/bash
set -o allexport
FOO=bar
bash -c 'echo $FOO'
[bchrisman (team/business_ps): scale-product] $ bash /tmp/a
bar
[bchrisman (team/business_ps): scale-product] $ shellcheck /tmp/a

In /tmp/a line 3:
FOO=bar
^-^ SC2034: FOO appears unused. Verify use (or export if used externally).

For more information:
  https://www.shellcheck.net/wiki/SC2034 -- FOO appears unused. Verify use (o...
[bchrisman (team/business_ps): scale-product] $

Here's what shellcheck currently says:

^-^ SC2034: FOO appears unused. Verify use (or export if used externally).

Here's what I wanted or expected to see:

<no output, as though the line was export FOO=bar

I might enjoy diving into the code and seeing if I can provide a fix if there are hints at where to start.

koalaman commented 3 years ago

You're certainly right. It's might be a bit tricky to fix though.

ShellCheck's handling of set -e is naively to look for set -e or equivalent anywhere in the script, and assume it's enabled for the whole script. Obviously it's trivial to trick with false && set -e, but it's worked well enough in practice.

I see from real-world examples that set -a is much more commonly used in blocks, like set -a; source "$file"; set +a;, so disabling all unused variable warnings may be too much. There's currently no robust way of seeing which assignments do and don't fall into such a block either, but pragmatically probably 95%+ of cases can be handled just by looking at commands between a set -a and set +a in any given block of code.

OJFord commented 2 years ago

Duplicate of #1986