Thursday, August 8, 2013

Newbie help: Finding yourself (assuming you're a script)

Sometimes a script needs to figure out its own filename.  This is useful when creating error output and logs -- basically, anytime that the source of a chunk of output might be ambiguous.  This is done via basename:

myname = `basename $0`

Why basename $0?  If you think about handling arguments in shell scripts, you'll recall that the first argument is $1, the second is $2, and so on.  So the full pathname of the script is the zeroth argument.  Basename simply strips that string down to the filename.

To do the same thing, but get the containing directory instead, use

mydir = `dirname $0`

Easy enough.

Unfortunately, $0 only gives you the path of the script as it was run.  So if we do this:

cd /opt/somedir
./subdir/script.sh

then dirname $0 will only return ./subdir .  That's not useful if we need to change directories during the course of script.sh without losing track of where we started.

Here's the solution:

SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P )

Spawn a subshell, cd into the directory using the relative or absolute path from dirname $0, and then print the working directory of the subshell.  This version resolves symlinks; omit the -P to preserve them.

(This post is mostly an excuse to write that last trick down.  Thanks to the folks on this post for coming up with it.)