title: Why does shellcheck fail when a source file is representing the variables at the top of a script?
body: <p><strong>Ubuntu 16.04<br>
  Bash 4.3.48</strong>  </p>
  
  <p>Why does <code>shellcheck</code> fail when a source file is representing the <em>$variables</em> at the top of a script?  </p>
  
  <p>Here is a simple script:  </p>
  
  <pre><code>#!/bin/bash
  
  . .sourcefile
  
  echo "Today is ${day}."
  </code></pre>
  
  <p>Here is my source file:  </p>
  
  <pre><code>day="Monday"
  </code></pre>
  
  <p>Here is the reply from <code>shellcheck</code>:  </p>
  
  <pre><code>me@myserver:~$ shellcheck start.sh
  
  In start.sh line 5:
  echo "Today is ${day}."
                 ^-- SC2154: day is referenced but not assigned.
  </code></pre>
  
  <p>Is there a way to let <code>shellcheck</code> know the <em>$variables</em> are in the source file?</p>
  
  <hr>
  
  <h2><strong>Here is what I did to make this work on Ubuntu 16.04</strong></h2>
  
  <p>@Dash-o explained the procedure below:  </p>
  
  <p>First, add the <em>source directive</em> on the line above the <em>source file</em> declaration like so:<br>
  <code># shellcheck source=/path/to/sourcefile</code></p>
  
  <pre><code>#!/bin/bash
  
  # shellcheck source=./.sourcefile
  . .sourcefile
  
  echo "Today is ${day}."
  </code></pre>
  
  <p>Next, execute <code>shellcheck</code> with the <strong>-x</strong> option before the script like so:<br>
  <code>shellcheck -x start.sh</code>  </p>
  
  <pre><code>me@myserver:~$ shellcheck -x start.sh
  </code></pre>
  
  <p>When using the <strong>-x</strong> option, <code>shellcheck</code> will follow the <em>source file</em> declared directly below the <em>source directive</em>. When I executed the command, I received the following error:</p>
  
  <pre><code>me@myserver:~$ shellcheck -x start.sh
  unrecognized option `-x'
  
  Usage: shellcheck [OPTIONS...] FILES...
    -e CODE1,CODE2..  --exclude=CODE1,CODE2..  exclude types of warnings
    -f FORMAT         --format=FORMAT          output format
    -s SHELLNAME      --shell=SHELLNAME        Specify dialect (bash,sh,ksh)
    -V                --version                Print version information
  </code></pre>
  
  <p>@Bayou mentioned my OS needed a newer version of <code>shellcheck</code>. I checked my Ubuntu 16.04 installation. My server had <code>shellcheck</code> 0.3.7, which is the latest version Ubuntu 16.04 had to offer, so I grabbed the latest binary from the <code>shellcheck</code> developers and installed it.</p>
  
  <pre><code>me@myserver:~$ mkdir .work &amp;&amp; cd .work
  me@myserver:~/.work$ wget -q https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.x86_64.tar.xz
  me@myserver:~/.work$ ls
  
  shellcheck-stable.linux.x86_64.tar.xz
  
  me@myserver:~/.work$ tar xvf shellcheck-stable.linux.x86_64.tar.xz
  
  shellcheck-stable/README.txt
  shellcheck-stable/LICENSE.txt
  shellcheck-stable/shellcheck
  
  me@myserver:~/.work$ sudo chown root: shellcheck-stable/shellcheck
  me@myserver:~/.work$ sudo mv /usr/bin/shellcheck .
  me@myserver:~/.work$ sudo mv shellcheck-stable/shellcheck /usr/bin/
  me@myserver:~/.work$ cd ../
  me@myserver:~$ rm -rf .work/
  me@myserver:~$ shellcheck -V
  
  ShellCheck - shell script analysis tool
  version: 0.7.1
  license: GNU General Public License, version 3
  website: https://www.shellcheck.net
  </code></pre>
  
  <p>I ran the command <code>shellcheck -x start.sh</code> and I received zero errors.  </p>
  
  <pre><code>me@myserver:~$ shellcheck -x start.sh
  </code></pre>
  
  <p>I then forced <code>shellcheck</code> to give me a few errors. I added <code>cat $myVariable</code> to the end of my script.  </p>
  
  <pre><code>me@myserver:~$ echo "cat \$myVariable" &gt;&gt; start.sh  
  me@myserver:~$ cat start.sh
  #!/bin/bash
  
  # shellcheck source=./.sourcefile
  . .sourcefile
  
  echo "Today is ${day}."
  cat $myVariable
  </code></pre>
  
  <p>I tested my theory and <code>shellcheck</code> followed my <em>sourcefile</em> and gave me errors I was expecting.  </p>
  
  <pre><code>me@myserver:~$ shellcheck -x start.sh
  
  In start.sh line 7:
  cat $myVariable
      ^---------^ SC2154: myVariable is referenced but not assigned.
      ^---------^ SC2086: Double quote to prevent globbing and word splitting.
  
  Did you mean:
  cat "$myVariable"
  
  For more information:
    https://www.shellcheck.net/wiki/SC2154 -- myVariable is referenced but not ...
    https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
  </code></pre>
  
  <p>Then I executed <code>shellcheck</code> without the <strong>-x</strong> option and to my surpise I received the following errors:  </p>
  
  <pre><code>me@myserver:~$ shellcheck start.sh
  
  In start.sh line 4:
  . .sourcefile
    ^---------^ SC1091: Not following: ./.sourcefile was not specified as input (see shellcheck -x).
  
  
  In start.sh line 6:
  echo "Today is ${day}."
                 ^----^ SC2154: day is referenced but not assigned.
  
  
  In start.sh line 7:
  cat $myVariable
      ^---------^ SC2154: myVariable is referenced but not assigned.
      ^---------^ SC2086: Double quote to prevent globbing and word splitting.
  
  Did you mean:
  cat "$myVariable"
  
  For more information:
    https://www.shellcheck.net/wiki/SC2154 -- day is referenced but not assigned.
    https://www.shellcheck.net/wiki/SC1091 -- Not following: ./.sourcefile was ...
    https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
  </code></pre>
  
  <p>So <code>shellcheck</code> updated to the latest version and without the <strong>-x</strong> option, will also give you an error about you mising the <strong>-x</strong> option on the command line. So I decided to comment out the <em>sourcefile directive</em> in my start.sh </p>
  
  <pre><code>me@myserver:~$ sed -i '3s/./#\ &amp;/' start.sh
  me@myserver:~$ cat start.sh
  #!/bin/bash
  
  # # shellcheck source=./.sourcefile
  . .sourcefile
  
  echo "Today is ${day}."
  cat $myVariable
  </code></pre>
  
  <p>Now to see what <code>shellcheck</code> thinks  </p>
  
  <pre><code>me@myserver:~$ shellcheck -x start.sh
  
  In start.sh line 7:
  cat $myVariable
      ^---------^ SC2154: myVariable is referenced but not assigned.
      ^---------^ SC2086: Double quote to prevent globbing and word splitting.
  
  Did you mean:
  cat "$myVariable"
  
  For more information:
    https://www.shellcheck.net/wiki/SC2154 -- myVariable is referenced but not ...
    https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
  </code></pre>
  
  <p>Whaaaaa? So it seems the <em>sourcefile directive</em> is really not needed with my simple script or is shellcheck still seeing the <em>sourcefile directive</em> being commented out with the number sign as the number sign already starts the <em>sourcefile directive</em>? So I removed the <em>sourcefile directive</em> altogether and commented out the last line which references the <em>myVariable</em> variable that is not assigned in the sourcefile.  </p>
  
  <pre><code>me@myserver:~$ sed -i '3d' start.sh
  me@myserver:~$ sed -i '$d' start.sh
  me@myserver:~$ cat start.sh
  #!/bin/bash
  
  . .sourcefile
  
  echo "Today is ${day}."  
  </code></pre>
  
  <p>Now to see what <code>shellcheck</code> reports:</p>
  
  <pre><code>me@myserver:~$ shellcheck -x start.sh
  </code></pre>
  
  <p>No errors with the <strong>-x</strong> option. Now to check if the <em>sourcefile directive</em> is not needed at the top of a simple shell script with latest version of <code>shellcheck</code> on Ubuntu 16.04, I executed <code>shellcheck</code> without the <strong>-x</strong> option.</p>
  
  <pre><code>me@myserver:~$ shellcheck start.sh
  
  In start.sh line 3:
  . .sourcefile
    ^---------^ SC1091: Not following: .sourcefile was not specified as input (see shellcheck -x).
  
  
  In start.sh line 5:
  echo "Today is ${day}."
                 ^----^ SC2154: day is referenced but not assigned.
  
  For more information:
    https://www.shellcheck.net/wiki/SC2154 -- day is referenced but not assigned.
    https://www.shellcheck.net/wiki/SC1091 -- Not following: .sourcefile was no...
  </code></pre>
  
  <p>So, in short, if <code>shellcheck</code> is not following your source file, update  <code>shellcheck</code> from the developer's github - (<a href="https://github.com/koalaman/shellcheck" rel="noreferrer">https://github.com/koalaman/shellcheck</a>) and inform <code>shellcheck</code> there is a sourcefile to follow by using the <strong>-x</strong> option like so:  </p>
  
  <pre><code>shellcheck -x script.sh  
  </code></pre>
  
  <p>I hope this helps someone as this site helps me each and everyday!</p>