Bash script own path

Bash script own path

am 19.12.2005 11:45:13 von wmsopou

How does a script find its own path?
$PWD gives me the path from which it is run, which is not nescessary
the path of the script file itself. On windows I would use "set
scriptpath=$~dp0".

Re: Bash script own path

am 19.12.2005 12:03:23 von Hubble

>How does a script find its own path?
>$PWD gives me the path from which it is run...

In short: you can't (reliably). Depending on the interactive shell or
invoking program, $0 contains the full path or not. Executables can use
execv to insert any string they like into $0. You can try using the
which command, if $0 does not supply the information

# error checking omitted
PROGNAME=`basename $0` # strip of path
PROGDIR=`dirname $0`

if [ "$PROGDIR" = "." ]
then
PROG=`which $PROGNAME`
PROGDIR=`dirname $PROG`
fi

Hubble.

Re: Bash script own path

am 19.12.2005 12:09:24 von Hubble

>How does a script find its own path?

On systems with a proc filesystem (cygwin, linux), you can find the
path there.

MYPATH=`cat /proc/$$/exename`

works reliably on cygwin (and probably linux).

Hubble.

Re: Bash script own path

am 19.12.2005 12:33:06 von wmsopou

I found out that i can:

progdir=`dirname $0`
cd $progdir
echo "scriptpath = $PWD"

now $PWD is the absolute path to the script.

Re: Bash script own path

am 19.12.2005 14:44:44 von dozzie

On 19.12.2005, Hubble wrote:
>>How does a script find its own path?
>>$PWD gives me the path from which it is run...
>
> In short: you can't (reliably). Depending on the interactive shell or
> invoking program, $0 contains the full path or not. Executables can use
> execv to insert any string they like into $0. You can try using the
> which command, if $0 does not supply the information
>
> # error checking omitted
> PROGNAME=`basename $0` # strip of path
> PROGDIR=`dirname $0`
>
> if [ "$PROGDIR" = "." ]
> then
> PROG=`which $PROGNAME`
> PROGDIR=`dirname $PROG`
> fi

#v+
$ cat > ls << 'EOF'
#!/bin/sh

PROGNAME=`basename $0` # strip of path
PROGDIR=`dirname $0`

if [ "$PROGDIR" = "." ]
then
PROG=`which $PROGNAME`
PROGDIR=`dirname $PROG`
fi
echo "$PROG"
EOF
$ chmod a+x ls
$ ./ls
#v-

What do you think, what will be printed?

#v+
#!/bin/sh

PROG=`which "$0"`
echo "$PROG"
: do something with "$PROG"
#v-

--
Feel free to correct my English
Stanislaw Klekot

Re: Bash script own path

am 19.12.2005 17:21:43 von Hubble

> PROG=`which "$0"`

which /usr/bin/ls
/usr/bin/ls: command not found

creates an error on my systems. Note that some shells insert the path
into $0, others don't. which does not handle this properly. My code
above will handle this situation. If you have the path already in $0,
you should use it.

Hubble.

Re: Bash script own path

am 19.12.2005 17:23:22 von Hubble

I found out that i can:


>progdir=`dirname $0`
>cd $progdir
>echo "scriptpath = $PWD"


>now $PWD is the absolute path to the script.

except that you have lost your working directory now. Otherwise it
seems to be a good solution.

Hubble.

Re: Bash script own path

am 19.12.2005 17:30:03 von Hubble

> How does a script find its own path?

Note that a C-Program can always set $0 as it likes, using execl. I can
do

main()
{ execl("/usr/bin/script","[xyz]",(void*)0);
}

invoking the process /usr/bin/script, but passing "[xyz]" as program
name. You will never find out where script is.

Most shells are kind enough to pass either

- the name "script"
- if invoked in the working dir the name ./script
- if invoked from the PATH the full path /usr/bin/script

Hubble.

Hubble.

Re: Bash script own path

am 19.12.2005 17:36:54 von Ed Morton

Hubble wrote:

> I found out that i can:
>
>
>
>>progdir=`dirname $0`
>>cd $progdir
>>echo "scriptpath = $PWD"
>
>
>
>>now $PWD is the absolute path to the script.
>
>
> except that you have lost your working directory now.

That can easily be solved by saving $PWD in a different variable before
doing the "cd".

Otherwise it
> seems to be a good solution.

No, it isn't. Try it with a script named, say, foo that's in your
$HOME/bin (which hopefully is in your PATH) and exeucte it from some
other directory as just "foo". It'll print the current working directory
instead of the scripts directory.

There's been many platform-dependent solutions for this posted over the
past couple of years - you should search the archives.

Ed.

Re: Bash script own path

am 19.12.2005 18:03:29 von dozzie

On 19.12.2005, Hubble wrote:
>> PROG=`which "$0"`
>
> which /usr/bin/ls
> /usr/bin/ls: command not found
>
> creates an error on my systems.

I can't reproduce this error.

#v+
[dozzie@hans dozzie]$ which /usr/bin/ls
/usr/bin/ls
[dozzie@hans dozzie]$ /usr/bin/which /usr/bin/ls
/usr/bin/ls
[dozzie@hans dozzie]$ cat /etc/slackware-version
Slackware 10.2.0 Extended
[dozzie@hans dozzie]$
#v-

#v+
[dozzie@dynamit dozzie]$ which /bin/ls
/bin/ls
[dozzie@dynamit dozzie]$ /usr/bin/which /bin/ls
/bin/ls
[dozzie@dynamit dozzie]$ cat /etc/debian_version
testing/unstable
[dozzie@dynamit dozzie]$
#v-

#v+
[klekot@b06 klekot]$ which /bin/ls
/bin/ls
[klekot@b06 klekot]$ /usr/bin/which /bin/ls
/bin/ls
[klekot@b06 klekot]$ uname -a
SunOS b06 5.8 Generic_117350-27 sun4u sparc SUNW,Sun-Blade-100
[klekot@b06 klekot]$
#v-

#v+
[klekot@b13 klekot]$ which /bin/ls
/bin/ls
[klekot@b13 klekot]$ /usr/bin/which /bin/ls
/bin/ls
[klekot@b13 klekot]$ uname -a
SunOS b13 5.9 Generic_118558-11 sun4u sparc SUNW,Sun-Blade-100
[klekot@b13 klekot]$
#v-

> Note that some shells insert the path
> into $0, others don't. which does not handle this properly.

Maybe your version of which. All my versions work well.

> My code
> above will handle this situation.

But your code doesn't handle other situation. You didn't even try your
code as I suggested. OK, I'll do it for you:
#v+
[dozzie@hans dozzie]$ cat > ls << 'EOF'
> #!/bin/sh
>
> PROGNAME=`basename $0` # strip of path
> PROGDIR=`dirname $0`
>
> if [ "$PROGDIR" = "." ]
> then
> PROG=`which $PROGNAME`
> PROGDIR=`dirname $PROG`
> fi
> echo "$PROG"
> EOF
[dozzie@hans dozzie]$ chmod a+x ls
[dozzie@hans dozzie]$ ./ls
/usr/bin/ls
[dozzie@hans dozzie]$ pwd
/home/dozzie
[dozzie@hans dozzie]$
#v-

> If you have the path already in $0,
> you should use it.

Of course I should. All /usr/bin/which versions available to me use the
path from $0.

--
Feel free to correct my English
Stanislaw Klekot

Re: Bash script own path

am 20.12.2005 08:18:16 von Hubble

>But your code doesn't handle other situation. You didn't even try your
>code as I suggested. OK, I'll do it for you:

As I said earlier, this (getting the path of a script) cannot be done
reliably. The version which I use is from cygwin, which gives the
error. If you can't reproduce the error, be aware that all systems are
(very!) different. I never claimed the code to be bullet proof, and
this is also what I said earlier. So I do not understand your reaction.

Hubble.

Re: Bash script own path

am 20.12.2005 12:45:48 von Hubble

>[dozzie@hans dozzie]$ ./ls

Ok, you always name your own skripts ls, cp, mv, awk and invoke them by
providing a relative path not in your PATH variable. That's ok.

Hubble.

Re: Bash script own path

am 20.12.2005 15:50:04 von dozzie

On 20.12.2005, Hubble wrote:
>>[dozzie@hans dozzie]$ ./ls
>
> Ok, you always name your own skripts ls, cp, mv, awk and invoke them by
> providing a relative path not in your PATH variable. That's ok.

And you always remember _all_ programs available in your system. That's
OK. But my systems have usually few thousands of binaries and scripts
available and I can't remember avery single file.
#v+
[dozzie@hans dozzie]$ (IFS=:; for P in $PATH; do ls -1 $P; done) | wc -l
2275
[dozzie@hans dozzie]$
#v-

--
Feel free to correct my English
Stanislaw Klekot

Re: Bash script own path

am 20.12.2005 16:11:39 von Hubble

>And you always remember _all_ programs available in your system

To break my code, you must also use a relative path to invoke your
script not in your PATH variable. Not very common. I doubt that you do
this, except when testing.

Hubble.

Re: Bash script own path

am 20.12.2005 16:32:31 von dozzie

On 20.12.2005, Hubble wrote:
>>But your code doesn't handle other situation. You didn't even try your
>>code as I suggested. OK, I'll do it for you:
>
> As I said earlier, this (getting the path of a script) cannot be done
> reliably.

Of course it can't. Every C programmer using some Unix could tell me the
same.

> The version which I use is from cygwin, which gives the
> error. If you can't reproduce the error, be aware that all systems are
> (very!) different. I never claimed the code to be bullet proof, and
> this is also what I said earlier. So I do not understand your reaction.

I've just installed recent version of Cygwin. I've checked
`which /bin/ls' command. Works very well, exactly as I expected: it gave
me "/bin/ls". It's GNU which, so I couldn't expect result other than
under Linux. Maybe some historic versions of `which' (three or more
years old) had that bug, I use unices just for 3 years and I simply
don't know.

--
Feel free to correct my English
Stanislaw Klekot

Re: Bash script own path

am 20.12.2005 23:17:35 von Bruce Barnett

"Stachu 'Dozzie' K." writes:

> It's GNU which, so I couldn't expect result other than
> under Linux. Maybe some historic versions of `which' (three or more
> years old) had that bug, I use unices just for 3 years and I simply
> don't know.

The original version of which was written in the C shell, and it read
the ~/.cshrc file to find out what csh aliases were defined before it
answered you.

--
Sending unsolicited commercial e-mail to this account incurs a fee of
$500 per message, and acknowledges the legality of this contract.

Re: Bash script own path

am 21.12.2005 08:21:00 von Hubble

>I've just installed recent version of Cygwin. I've checked
>`which /bin/ls' command. Works very well, exactly as I expected: it gave
>me "/bin/ls". It's GNU which, so I couldn't expect result other than
>under Linux. Maybe some historic versions of `which' (three or more
>years old) had that bug, I use unices just for 3 years and I simply
>don't know.

$ uname -a
CYGWIN_NT-5.0 hubble1.5.10(0.116/4/2) 2004-05-25 22:07 i686 unknown
unknown Cygwin

$ which which
/usr/bin/which

$ which ls
/usr/bin/ls

$ which /usr/bin/ls
/usr/bin/ls: Command not found.

That's why I did not feed $0 directly to this broken version of which.
A new version of cygwin (CYGWIN_NT-5.1) works well.

Hubble.