title: Reliable way for a Bash script to get the full path to itself
body: <p>I have a Bash script that needs to know its full path. I'm trying to find a broadly-compatible way of doing that without ending up with relative or funky-looking paths. I only need to support Bash, not sh, csh, etc.</p>
  
  <p>What I've found so far:</p>
  
  <ol>
  <li><p>The accepted answer to <em><a href="https://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in">Getting the source directory of a Bash script from within</a></em> addresses getting the path of the script via <code>dirname $0</code>, which is fine, but that may return a <em>relative</em> path (like <code>.</code>), which is a problem if you want to change directories in the script and have the path still point to the script's directory. Still, <code>dirname</code> will be part of the puzzle.</p></li>
  <li><p>The accepted answer to <em><a href="https://stackoverflow.com/questions/3572030/bash-script-absolute-path-with-osx">Bash script absolute path with OS X</a></em> <em>(OS X specific, but the answer works regardless)</em> gives a function that will test to see if <code>$0</code> looks relative and if so will pre-pend <code>$PWD</code> to it. But the result can still have relative bits in it (although overall it's absolute)&nbsp;&mdash; for instance, if the script is <code>t</code> in the directory <code>/usr/bin</code> and you're in <code>/usr</code> and you type <code>bin/../bin/t</code> to run it (yes, that's convoluted), you end up with <code>/usr/bin/../bin</code> as the script's directory path. Which <strong>works</strong>, but...</p></li>
  <li><p>The <code>readlink</code> solution <a href="https://web.archive.org/web/20110620064726/http://fritzthomas.com/open-source/linux/384-how-to-get-the-absolute-path-within-the-running-bash-script/" rel="noreferrer">on this page</a>, which looks like this:</p>
  
  <pre><code># Absolute path to this script. /home/user/bin/foo.sh
  SCRIPT=$(readlink -f $0)
  # Absolute path this script is in. /home/user/bin
  SCRIPTPATH=`dirname $SCRIPT`
  </code></pre>
  
  <p>But <code>readlink</code> isn't POSIX and apparently the solution relies on GNU's <code>readlink</code> where BSD's won't work for some reason (I don't have access to a BSD-like system to check).</p></li>
  </ol>
  
  <p>So, various ways of doing it, but they all have their caveats.</p>
  
  <p>What would be a better way? Where "better" means:</p>
  
  <ul>
  <li>Gives me the absolute path.</li>
  <li>Takes out funky bits even when invoked in a convoluted way (see comment on #2 above). (E.g., at least moderately canonicalizes the path.)</li>
  <li>Relies only on Bash-isms or things that are almost certain to be on most popular flavors of *nix systems (GNU/Linux, BSD and BSD-like systems like OS&nbsp;X, etc.).</li>
  <li>Avoids calling external programs if possible (e.g., prefers Bash built-ins).</li>
  <li>(<strong>Updated</strong>, thanks for the heads up, <a href="https://stackoverflow.com/users/251414/wich">wich</a>) It doesn't have to resolve symlinks (in fact, I'd kind of prefer it left them alone, but that's not a requirement).</li>
  </ul>