Unix Shell - Script sourced by bash -- can it determine it's own location?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > September 2007 > Script sourced by bash -- can it determine it's own location?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Script sourced by bash -- can it determine it's own location?
google@scottg.net

2007-09-16, 7:19 pm

I'm trying to figure out how a script that is sourced at the command
line can determine it's own location, such that for the file ~/test/
script.sh:

# script.sh
export MYLOCATION=???

when I do:

bash# cd $HOME
bash# source test/script.sh

or

bash# cd /etc
bash# source /home/scott/test/script.sh

MYLOCATION is set to be the directory where script.sh lives which is,
in all cases, the same each time.

thanks,

/s.

Icarus Sparry

2007-09-17, 1:25 am

On Sun, 16 Sep 2007 16:24:11 -0700, google wrote:

> I'm trying to figure out how a script that is sourced at the command
> line can determine it's own location, such that for the file ~/test/
> script.sh:
>
> # script.sh
> export MYLOCATION=???
>
> when I do:
>
> bash# cd $HOME
> bash# source test/script.sh
>
> or
>
> bash# cd /etc
> bash# source /home/scott/test/script.sh
>
> MYLOCATION is set to be the directory where script.sh lives which is, in
> all cases, the same each time.


In general you can't.

You can use 'history 1' to see how the command was entered, and then
write something to parse that. This will give you something that works in
many cases. However it is by no means foolproof.

Cyrus Kriticos

2007-09-17, 1:25 am

google@scottg.net wrote:
> I'm trying to figure out how a script that is sourced at the command
> line can determine it's own location, such that for the file ~/test/
> script.sh:
>
> # script.sh
> export MYLOCATION=???


with bash version >= 3.0:

export MYLOCATION=${BASH_ARGV[0]%/*}

--
Best regards | "The only way to really learn scripting is to write
Cyrus | scripts." -- Advanced Bash-Scripting Guide
Cyrus Kriticos

2007-09-17, 1:25 am

google@scottg.net wrote:
> I'm trying to figure out how a script that is sourced at the command
> line can determine it's own location, such that for the file ~/test/
> script.sh:
>
> # script.sh
> export MYLOCATION=???


with bash version >= 3.0:

MYLOCATION="${PWD}/${BASH_ARGV[0]}"
export MYLOCATION="${MYLOCATION%/*}"

--
Best regards | "The only way to really learn scripting is to write
Cyrus | scripts." -- Advanced Bash-Scripting Guide
google@scottg.net

2007-09-17, 1:29 pm

Thanks, Cyrus, your code below worked and I have control over what
shell is available on the system. I couldn't find a clean way to
normalize the path name when a relative path to the source file was
used, but that's easily worked around by changing into the target's
directory and using PWD to set the var before jumping back to the
previous directory.

/s.

On Sep 17, 12:28 am, Cyrus Kriticos <cyrus.kriti...@googlemail.com>
wrote:
> goo...@scottg.net wrote:
>
>
> with bash version >= 3.0:
>
> MYLOCATION="${PWD}/${BASH_ARGV[0]}"
> export MYLOCATION="${MYLOCATION%/*}"
>
> --
> Best regards | "The only way to really learn scripting is to write
> Cyrus | scripts." -- Advanced Bash-Scripting Guide



bsh

2007-09-17, 7:22 pm

On Sep 17, 6:07 am, goo...@scottg.net wrote:
> I couldn't find a clean way to
> normalize the path name when a relative path to the source file was
> used, ...


The resolution of the pathname in $0, and its normalization, via
symlinks
and otherwise, is addressed in my script "resolvepath" below:

http://groups.google.com/group/comp...3b2b4fef10d3717

It's a trickier problem than is generally realized, as there are many
problematic cases. The only problem is that it's a ksh(1) function.
Bash3
_should_ work without editing, although I haven't tested this.

I think you want: resolvepath -lp "$0"

=Brian

Stephane CHAZELAS

2007-09-18, 7:29 am

2007-09-17, 17:10(-07), bsh:
[...]
> I think you want: resolvepath -lp "$0"

[...]

I've not had a look at your script, but I suspect it will not
work. $0 contains the path of the script or "bash", not the path
of the currently sourced file. bash (recent versions) has
"${BASH_SOURCE[0]}" for that.

--
Stéphane
bsh

2007-09-19, 7:20 pm

On Sep 18, 12:05 am, Stephane CHAZELAS <this.addr...@is.invalid>
wrote:
> 2007-09-17, 17:10(-07), bsh:
> I've not had a look at your script, but I suspect it will not
> work. $0 contains the path of the script or "bash", not the path
> of the currently sourced file. bash (recent versions) has
> "${BASH_SOURCE[0]}" for that.


You're right, St=E9phane. The OQ is partially elided in my
reader, and I did not correctly understand its intention. To
answer this -- and resolvepath may still be of some assistance
-- is that sh and ksh88 do not assign $0 other than the path of
the invoking script, but that _latter versions_ of ksh93 do
indeed set the shell parameter ".sh.fun" to the name of the
current function.

I've performed a workaround in the past where I've explicitly
preloaded the environment of the function with its name. IIRC,
it's something like:

alias foo=3D'SOURCE_NAME=3Dfoo foo' # do for each function ...
foo { print $SOURCE_NAME; }
foo

An enumerated list of function names may even be generated with the
"typeset +f" command, and used to feed the above statement in a loop.
I vaguely remember something about there needing to be a pseudo-
autoload to preset the function namespace if the list was to be
generated
before the functions were themselves defined.

# not tested
for f in $( typeset +f )
do eval "alias $f=3D'SOURCE_NAME=3D$f $f'"
done

=3DBrian

Tiago Peczenyj

2007-09-20, 1:27 am

$ pwd
/home/peczenyj

$ cat test/script.sh
set | grep BASH_ARGV | cut -d\" -f2 | head -1 | xargs -i echo ${PWD}/
{} > /tmp/xxx
read MYVAR < /tmp/xxx

$ source test/script

$ echo $MYVAR
/home/visitante/test/script.sh



On 19 set, 21:10, bsh <brian_hi...@rocketmail.com> wrote:
> On Sep 18, 12:05 am, Stephane CHAZELAS <this.addr...@is.invalid>
> wrote:
>
>
> You're right, St=E9phane. The OQ is partially elided in my
> reader, and I did not correctly understand its intention. To
> answer this -- and resolvepath may still be of some assistance
> -- is that sh and ksh88 do not assign $0 other than the path of
> the invoking script, but that _latter versions_ of ksh93 do
> indeed set the shell parameter ".sh.fun" to the name of the
> current function.
>
> I've performed a workaround in the past where I've explicitly
> preloaded the environment of the function with its name. IIRC,
> it's something like:
>
> alias foo=3D'SOURCE_NAME=3Dfoo foo' # do for each function ...
> foo { print $SOURCE_NAME; }
> foo
>
> An enumerated list of function names may even be generated with the
> "typeset +f" command, and used to feed the above statement in a loop.
> I vaguely remember something about there needing to be a pseudo-
> autoload to preset the function namespace if the list was to be
> generated
> before the functions were themselves defined.
>
> # not tested
> for f in $( typeset +f )
> do eval "alias $f=3D'SOURCE_NAME=3D$f $f'"
> done
>
> =3DBrian



bsh

2007-09-20, 7:21 pm

Tiago Peczenyj <tiago.pecze...@gmail.com> wrote:
> $ pwd
> /home/peczenyj
> $ cat test/script.sh
> set | grep BASH_ARGV | cut -d\" -f2 | head -1 | xargs -i echo ${PWD}/
> {} > /tmp/xxx
> read MYVAR < /tmp/xxx
> $ source test/script
> $ echo $MYVAR


Horrors! Five subprocesses/subshell-environments and one temporary
file,
for nothing more than to feed one variable?! As for myself, when I
write
functions, at least when intended to be portable, I try to implement
them
without resorting to any fork/exec, if at all possible.

I'd at least collapse the grep/cut/head/xargs into one sed script.

=Brian


Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2009 webservertalk.com