views:

1985

answers:

6

I'm converting some Windows batch files to Unix scripts using sh. I have problems because some behavior is dependent on the %~dp0 macro available in batch files.

Is there any sh equivalent to this? Any way to obtain the directory where the executing script lives?

A: 

Yes, you can! It's in the arguments. :)

look at

${0}

combining that with

{$var%Pattern}
Remove from $var  the shortest part of $Pattern that matches the back end of $var.

what you want is just

${0%/*}

I recommend the Advanced Bash Scripting Guide (that is also where the above information is from). Especiall the part on Converting DOS Batch Files to Shell Scripts might be useful for you. :)

If I have misunderstood you, you may have to combine that with the output of "pwd". Since it only contains the path the script was called with! Try the following script:

#!/bin/bash
called_path=${0%/*}
stripped=${called_path#[^/]*}
real_path=`pwd`$stripped
echo "called path: $called_path"
echo "stripped: $stripped"
echo "pwd: `pwd`"
echo "real path: $real_path

This needs some work though. I recommend using Dave Webb's approach unless that is impossible.

Corporal Touchy
A: 

Try this:

${0%/*}
Chris Jester-Young
A: 

I have tried $0 before, namely:

dirname $0

and it just returns "." even when the script is being sourced by another script:

. ../somedir/somescript.sh

paulo.albuquerque
can you post the exact script you tried? or an example
Corporal Touchy
+1  A: 

The problem (for you) with $0 is that it is set to whatever command line was use to invoke the script, not the location of the script itself. This can make it difficult to get the full path of the directory containing the script which is what you get from %~dp0 in a Windows batch file.

For example, consider the following script, dollar.sh:

#!/bin/bash
echo $0

If you'd run it you'll get the following output:

# ./dollar.sh
./dollar.sh
# /tmp/dollar.sh
/tmp/dollar.sh

So to get the fully qualified directory name of a script I do the following:

cd `dirname $0`
SCRIPTDIR=`pwd`
cd -

This works as follows:

  1. cd to the directory of the script, using either the relative or absolute path from the command line.
  2. Gets the absolute path of this directory and stores it in SCRIPTDIR.
  3. Goes back to the previous working directory using "cd -".
Dave Webb
If changing the working directory is undesirable I added another appraoch.
Corporal Touchy
The the script is in the path and not being called directly, then $0 will be just the name of the script and this method will not work.
Steve Baker
+1  A: 

I was trying to find the path for a script that was being sourced from another script. And that was my problem, when sourcing the text just gets copied into the calling script, so $0 always returns information about the calling script.

I found a workaround, that only works in bash, $BASH_SOURCE always has the info about the script in which it is referred to. Even if the script is sourced it is correctly resolved to the original (sourced) script.

paulo.albuquerque
+1  A: 

In bash under linux you can get the full path to the command with:

readlink /proc/$$/fd/255

and to get the directory:

dir=$(dirname $(readlink /proc/$$/fd/255))

It's ugly, but I have yet to find another way.

Steve Baker