title: Find all variables used in a shell script
body: <p>I'm trying to write a program that finds all variables <strong>used</strong> in a shell script (note; used, not declared). e.g., if I give it something like this:</p>
  <pre><code>cdo_verbosity() {
          if [ &quot;x$CDO_QUIET&quot; == &quot;x1&quot; ]; then
                  cdo=&quot;cdo -s&quot;
          elif [ &quot;x$CDO_VERBOSE&quot; == &quot;x1&quot; ]; then
                  cdo=&quot;cdo -v&quot;
          else
                  cdo=cdo
          fi
  }
  </code></pre>
  <p>I would get back a list of:</p>
  <pre><code>CDO_QUIET
  CDO_VERBOSE
  </code></pre>
  <p>I've found a few posts that recommend something like this:</p>
  <pre class="lang-sh prettyprint-override"><code>function extract_variables() {
          script=$1
          echo &quot;Extracting variables from $script&quot;
          ( set -o posix; set ) &gt; /tmp/variables.before
          source $script
          ( set -o posix ; set ) &gt;/tmp/variables.after
          diff /tmp/variables.before /tmp/variables.after &gt; variables_defined_in_${script}.dat
          rm /tmp/variables.before /tmp/variables.after
  }
  
  </code></pre>
  <p>However, that seems to work only for variables that are declared rather than used. Note that the input script has all sort of shell-isms, e.g. <code>${var:-default}</code>, <code>$var</code>, <code>${var_with_words}</code>, <code>eval ${nested_${var}}</code>, so it's not necessarily as simple as &quot;find everything with a $&quot;</p>
  <p>Target language for the solution program is arbitrary, but I'd prefer to write it in shell or Python...</p>
  <p>Any help would be greatly appreciated!!</p>