Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Determining the full path to a running script

8 views
Skip to first unread message

Yanko

unread,
Feb 16, 2007, 11:00:26 AM2/16/07
to
Hello everyone:

I have a script that needs an external file (located in the same
directory as the script) to complete his task. I also need that this
script/file pair can be moved to different paths without modifying
the original script.

So my question is: how can I determine the dirname of a running
script? A little example would be really appreciated. I have already
tried with $(diname ${0}) but it doesn't solve the problem. For
example, given a script located in /home/user/test/script.sh:
----
#!/bin/bash
echo $(dirname ${0})
----

depending on how you call it gives you different results:
$ test/script.sh
test
$ ./test/script.sh
./test
$ /home/user/test/script.sh
/home/user/test
$ cd test; ./script.sh
.

Is there an easy way to determine this?

yanko

OldSchool

unread,
Feb 16, 2007, 11:23:03 AM2/16/07
to

two simple options:

wrk_dir=$(dirname ${0})
cd $wrk_dir
<read or whatever> target.file

or
wrk_dir=$(dirname ${0})
<read or whatever> $wrk_dir/target.file

where target.file is in the same directory as the script that accesses
it

Daniel Rock

unread,
Feb 16, 2007, 11:48:50 AM2/16/07
to
Yanko <yhdeza...@gmail.com> wrote:
> depending on how you call it gives you different results:
> $ test/script.sh
> test
> $ ./test/script.sh
> ./test
> $ /home/user/test/script.sh
> /home/user/test
> $ cd test; ./script.sh
> .
>
> Is there an easy way to determine this?

If you don't change directories, it doesn't matter if you work with
an absolute or relative pathname.


If you want to use an absolute pathname:

basedir=$(cd "$(dirname "$0")"; pwd)

--
Daniel

Yanko

unread,
Feb 16, 2007, 12:17:35 PM2/16/07
to

> If you don't change directories, it doesn't matter if you work with
> an absolute or relative pathname.


of course... you are right... tunnel vision from my side... too much
time trying to determine the absolute pathname... hehe... sorry

> basedir=$(cd "$(dirname "$0")"; pwd)

and a nice way to do it...

thank you very much... (OldSchool that goes to you too ;-) thank you
guys.

Bill Seivert

unread,
Feb 19, 2007, 1:34:36 AM2/19/07
to
thispath=$(ksh -c "type \"$0\"")
thisdir=$(dirname "$thispath")

Bill Seivert

Stephane CHAZELAS

unread,
Feb 19, 2007, 7:29:52 AM2/19/07
to
2007-02-18, 23:34(-07), Bill Seivert:
[...]

> thispath=$(ksh -c "type \"$0\"")

No, that's wrong, and not only because type returns "foo is
/usr/bin/foo" or that ksh is a non-standard command.

Except with some old boggus versions of ksh,

sh script.sh

Tries to run "script.sh" in the current directory, before
attempting to look it up in $PATH.

In a POSIX shell:

dir=$(
cmd=$0
[ -e "$cmd" ] || cmd=$(command -v -- "$cmd") || exit
cd -P -- "$(dirname -- "$cmd")" && pwd -P


)

> thisdir=$(dirname "$thispath")
>
> Bill Seivert


--
Stéphane

Geoff Clare

unread,
Feb 19, 2007, 8:56:14 AM2/19/07
to
Stephane CHAZELAS <this.a...@is.invalid> wrote, on Mon, 19 Feb 2007:

> In a POSIX shell:
>
> dir=$(
> cmd=$0
> [ -e "$cmd" ] || cmd=$(command -v -- "$cmd") || exit
> cd -P -- "$(dirname -- "$cmd")" && pwd -P
> )

That won't work with some values of CDPATH, as cd will output
the directory name itself if a non-empty string from CDPATH is
used. Instead of

cd -P -- "$(dirname -- "$cmd")" && pwd -P

you need either

cd -P -- "$(dirname -- "$cmd")" >/dev/null && pwd -P

or

unset CDPATH


cd -P -- "$(dirname -- "$cmd")" && pwd -P

--
Geoff Clare <net...@gclare.org.uk>

Stephane CHAZELAS

unread,
Feb 19, 2007, 9:29:45 AM2/19/07
to
2007-02-19, 13:56(+00), Geoff Clare:

> Stephane CHAZELAS <this.a...@is.invalid> wrote, on Mon, 19 Feb 2007:
>
>> In a POSIX shell:
>>
>> dir=$(
>> cmd=$0
>> [ -e "$cmd" ] || cmd=$(command -v -- "$cmd") || exit
>> cd -P -- "$(dirname -- "$cmd")" && pwd -P
>> )
>
> That won't work with some values of CDPATH, as cd will output
> the directory name itself if a non-empty string from CDPATH is
> used. Instead of
>
> cd -P -- "$(dirname -- "$cmd")" && pwd -P
[...]

Are you saying that CDPATH may be inherited from the
environement in non-interactive shells?!

Surely POSIX can't have specified such a nonsense, can it?

sigh... it looks like it did.

Does that mean one has to add "unset CDPATH" to the top of every
script that may use "cd"?

Or is it one of the "if there's CDPATH in the environment, then
it's not a POSIX environement, so the behavior is unspecified".

Is it specified anywhere (as a warning) which is the list of
environment variables that may have an impact on the behavior of
a script (like PATH, PWD, PS4, TMPDIR, TMOUT, CDPATH, SECONDS...)

--
Stéphane

Geoff Clare

unread,
Feb 20, 2007, 9:06:24 AM2/20/07
to
Stephane CHAZELAS <this.a...@is.invalid> wrote, on Mon, 19 Feb 2007:

>> That won't work with some values of CDPATH, as cd will output
>> the directory name itself if a non-empty string from CDPATH is
>> used.

> Are you saying that CDPATH may be inherited from the


> environement in non-interactive shells?!
>
> Surely POSIX can't have specified such a nonsense, can it?
>
> sigh... it looks like it did.

Presumably POSIX.2-1992 specified it because it was existing
practice in Bourne-type shells (particularly ksh) at the time.
Are there any modern shells which ignore an inherited CDPATH when
a non-interactive shell starts?

Even if CDPATH is ignored from the environment, there is still
the possibility that it could be set in a shell startup file.
(It would have to be one which is sourced by non-interactive
shells - like $BASH_ENV, or $ENV in old pre-POSIX ksh.)

> Does that mean one has to add "unset CDPATH" to the top of every
> script that may use "cd"?

Yes, if you want to prevent misbehaviour caused by bad CDPATH
values. If you trust CDPATH to be reasonable, but allow for the
fact that it might start with ".:" then just redirecting the output
of cd to /dev/null when it is not wanted is sufficient.

> Or is it one of the "if there's CDPATH in the environment, then
> it's not a POSIX environement, so the behavior is unspecified".

No, since POSIX specifies the CDPATH environment variable.

> Is it specified anywhere (as a warning) which is the list of
> environment variables that may have an impact on the behavior of
> a script (like PATH, PWD, PS4, TMPDIR, TMOUT, CDPATH, SECONDS...)

I'm not aware of any such list.

--
Geoff Clare <net...@gclare.org.uk>

Stephane CHAZELAS

unread,
Feb 20, 2007, 2:59:46 PM2/20/07
to
2007-02-20, 14:06(+00), Geoff Clare:
[...]

> Yes, if you want to prevent misbehaviour caused by bad CDPATH
> values. If you trust CDPATH to be reasonable, but allow for the
> fact that it might start with ".:" then just redirecting the output
> of cd to /dev/null when it is not wanted is sufficient.

What's a reasonable CDPATH? CDPATH is there for the shell user
to be able to cd into directories that are not subdirs of the
current one. It is definitely incompatible with what is expected
of a script. I can't see any reason why a script would make use
of the $CDPATH that it got from its environment. That's a bug in
the spec, to me.

>> Or is it one of the "if there's CDPATH in the environment, then
>> it's not a POSIX environement, so the behavior is unspecified".
>
> No, since POSIX specifies the CDPATH environment variable.
>
>> Is it specified anywhere (as a warning) which is the list of
>> environment variables that may have an impact on the behavior of
>> a script (like PATH, PWD, PS4, TMPDIR, TMOUT, CDPATH, SECONDS...)
>
> I'm not aware of any such list.

BTW, how would POSIX qualify the behavior of a shell that for

TMOUT=1 sh -c read

returns with a 1 exit code after 1 second?

That's the behavior of ksh93

What about

FIGNORE='!(..)' sh -c 'echo *'

which returns "." still with ksh93.


--
Stéphane

Geoff Clare

unread,
Feb 21, 2007, 9:05:47 AM2/21/07
to
Stephane CHAZELAS <this.a...@is.invalid> wrote, on Tue, 20 Feb 2007:

> 2007-02-20, 14:06(+00), Geoff Clare:
> [...]
>> Yes, if you want to prevent misbehaviour caused by bad CDPATH
>> values. If you trust CDPATH to be reasonable, but allow for the
>> fact that it might start with ".:" then just redirecting the output
>> of cd to /dev/null when it is not wanted is sufficient.
>
> What's a reasonable CDPATH?

One that causes the current directory to be searched first.
(I.e. either empty or starting with ":" or ".:").

> CDPATH is there for the shell user
> to be able to cd into directories that are not subdirs of the
> current one. It is definitely incompatible with what is expected
> of a script. I can't see any reason why a script would make use
> of the $CDPATH that it got from its environment. That's a bug in
> the spec, to me.

I agree it's an unfortunate feature. If there is a "bug" then it
was in the existing shell implementation(s) which POSIX.2
standardised.

>>> Or is it one of the "if there's CDPATH in the environment, then
>>> it's not a POSIX environement, so the behavior is unspecified".
>>
>> No, since POSIX specifies the CDPATH environment variable.
>>
>>> Is it specified anywhere (as a warning) which is the list of
>>> environment variables that may have an impact on the behavior of
>>> a script (like PATH, PWD, PS4, TMPDIR, TMOUT, CDPATH, SECONDS...)
>>
>> I'm not aware of any such list.
>
> BTW, how would POSIX qualify the behavior of a shell that for
>
> TMOUT=1 sh -c read
>
> returns with a 1 exit code after 1 second?
>
> That's the behavior of ksh93
>
> What about
>
> FIGNORE='!(..)' sh -c 'echo *'
>
> which returns "." still with ksh93.

XSH6 section 8.1 Environment Variable Definition says:

The name space of environment variable names containing lowercase
letters is reserved for applications. Applications can define any
environment variables with names from this name space without
modifying the behavior of the standard utilities.

This implies that if an application (or user) sets any non-standard
environment variable with a name that does not contain any lowercase
letters then it can affect the behaviour of the standard utilities.
In practice, of course, many applications do set such variables (or
require users to set them to control the application) and clashes
are rare. However, when clashes do occur it is (according to POSIX)
the fault of the application for not using a name containing at least
one lowercase letter. Careful choice of variable names helps, e.g.
always using the application name as a prefix.

--
Geoff Clare <net...@gclare.org.uk>

0 new messages