[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: PATH and $0

From: Bob Proulx
Subject: Re: PATH and $0
Date: Thu, 13 Jul 2006 23:53:00 -0600
User-agent: Mutt/1.5.9i

Stephane Chazelas wrote:
> $0 will always  contain the file path, unless the script was
> started as:
> bash script.sh
> And there's no script.sh in the current directory (in which case
> sh/bash will have looked up script.sh in $PATH).

Of course using command as you have done will work for bash.  But I
always feel better about using portable shell as much as possible.
here is one way.

  pathfind() {
    for p in $PATH; do
      if [ -x "$p/$*" ]; then
        echo "$p/$*"

> #! /bin/sh -
> dir=$(
>   cmd=$0
>   [ -e "$cmd" ] || cmd=$(command -v -- "$cmd") || exit
>   dir=$(dirname -- "$cmd")
>   cd -P -- "$dir" && pwd -P
> ) || exit
> # untested
> should give you the absolute path of the directory portion of
> the script path (unless that directory ends in newline
> characters).

One thing to note about this script is that it canonicalizes path with
respect to symlinks.  You do say that but without much fanfare.  It
raises a red flag for me.  I think that canonicalizing the path is
doing too much.  You did say untested and I acknowledge the caveats
you were trying to warn about.

Here is a problem.  Let's say a binary lives on an automounted
partition such as the old BSD amd.  PATH can point to the trigger
directory (e.g. /net/foo) and so searching there will trigger a mount
operation.  The actual location may be /.automount/net/foo with a
symlink to it and that is the path that will be returned by the above.
Enough time might passes that amd unmounts the directory.  Now when
access to $0 or the directory above is attempted in the future with
that path it will fail because the directory is not mounted and not
going through the trigger directory it won't be mounted.  This is
unexpected to the user.

I think it is best to accept whatever path the user has provided
verbatim.  I would not try to canonicalize the path in any way.  If
the user has provided a path with /foo/bar/../../zoo/zam for example
then I would just go with it because that path may actually be
necessary just like that for some reason as yet unknown at this moment
to us writing the code to be used in the future.  The reason I think
this way is that I have tried to do things like canonicalizing
previously myself and gotten burned by it.  I have learned it is
better to avoid doing such things.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]