|
Home > Archive > Unix Shell > January 2006 > How to tell if a (script) file is being dotted?
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 |
How to tell if a (script) file is being dotted?
|
|
| jrw32982@yahoo.com 2006-01-13, 10:40 pm |
| I believe I can accomplish this by comparing the value of $0 with the
name of the file. $0 appears to be the calling script if a file is
being dotted or the file itself if it is being run directly. But what
if I don't know (or don't want to hardcode) the name of the file that
contains the code being run? Is there a *direct* way of telling in ksh
or bash that code is being run from a dotted file rather than from a
file being executed directly by the interpreter?
In other words, can you distinguish the following two cases, without
using the string "myfile"?
.. ./myfile
../myfile
-- John Wiersba
| |
| Stephane CHAZELAS 2006-01-13, 10:40 pm |
| 2006-01-10, 11:57(-08), jrw32982@yahoo.com:
> I believe I can accomplish this by comparing the value of $0 with the
> name of the file. $0 appears to be the calling script if a file is
> being dotted or the file itself if it is being run directly. But what
> if I don't know (or don't want to hardcode) the name of the file that
> contains the code being run? Is there a *direct* way of telling in ksh
> or bash that code is being run from a dotted file rather than from a
> file being executed directly by the interpreter?
[...]
What if the code is in a function? What do you want to know?
Where that function was defined? Which file the shell was
interpreting when the function was defined? The file the shell
is interpreting at the time the function is called?
a.sh:
.. ./b.sh
g
b.sh:
.. ./c.sh
f
c.sh:
f() {
g() {
where am I?
}
}
When running a.sh, what to you want "where am I" to return?
What about "eval" statements?
See the BASH_SOURCE and FUNCNAME arrays in bash3.
See print -P %N in zsh.
--
Stéphane
| |
| jrw32982@yahoo.com 2006-01-13, 10:40 pm |
| I have a file/script which defines a couple of functions. If dotted,
the functions can be used within the context of the script which dotted
the functions. But if called directly, I want the file to
automatically call the "main" function defined in that script. In
other words, I have two usage patterns in mind:
.. ./myfile
# other stuff here
myfunc 1 2 3 # runs in calling process
or
../myfile 1 2 3 # runs in separate process
| |
| Michael Tosch 2006-01-13, 10:40 pm |
| jrw32982@yahoo.com wrote:
> I believe I can accomplish this by comparing the value of $0 with the
> name of the file. $0 appears to be the calling script if a file is
> being dotted or the file itself if it is being run directly. But what
> if I don't know (or don't want to hardcode) the name of the file that
> contains the code being run? Is there a *direct* way of telling in ksh
> or bash that code is being run from a dotted file rather than from a
> file being executed directly by the interpreter?
>
> In other words, can you distinguish the following two cases, without
> using the string "myfile"?
>
> . ./myfile
> ./myfile
>
bash (2.x) seems to always set $_ to bash when a new shell is invoked.
So this should mostly work:
#!/bin/bash
if [ "${_##*/}" = "bash" ]; then
echo "invoked"
else
echo "included"
fi
--
Michael Tosch @ hp : com
| |
| Stephane CHAZELAS 2006-01-13, 10:40 pm |
| 2006-01-10, 12:30(-08), jrw32982@yahoo.com:
> I have a file/script which defines a couple of functions. If dotted,
> the functions can be used within the context of the script which dotted
> the functions. But if called directly, I want the file to
> automatically call the "main" function defined in that script. In
> other words, I have two usage patterns in mind:
>
> . ./myfile
> # other stuff here
> myfunc 1 2 3 # runs in calling process
>
> or
>
> ./myfile 1 2 3 # runs in separate process
With bash, you can put at the end of myfile:
eval return 2> /dev/null
myfunc "$@"
"return" will return only from a doted file.
That won't necessarily work with other shells as the behavior of
return in a non-dotted script is /unspecified/.
--
Stéphane
| |
| Stephane CHAZELAS 2006-01-13, 10:40 pm |
| 2006-01-10, 12:30(-08), jrw32982@yahoo.com:
> I have a file/script which defines a couple of functions. If dotted,
> the functions can be used within the context of the script which dotted
> the functions. But if called directly, I want the file to
> automatically call the "main" function defined in that script. In
> other words, I have two usage patterns in mind:
>
> . ./myfile
> # other stuff here
> myfunc 1 2 3 # runs in calling process
>
> or
>
> ./myfile 1 2 3 # runs in separate process
You may start your file with:
#! /bin/sh /path/to/run
And /path/to/run being a file that contains:
if . "$0"; then
shift
myfunc "$@"
fi
--
Stéphane
| |
| Michael Tosch 2006-01-13, 10:40 pm |
| jrw32982@yahoo.com wrote:
> I have a file/script which defines a couple of functions. If dotted,
> the functions can be used within the context of the script which dotted
> the functions. But if called directly, I want the file to
> automatically call the "main" function defined in that script. In
> other words, I have two usage patterns in mind:
>
> . ./myfile
> # other stuff here
> myfunc 1 2 3 # runs in calling process
>
> or
>
> ./myfile 1 2 3 # runs in separate process
>
So you would be fine if you could test if a certain function is defined,
without calling that function.
This is possible with aliases, but with functions??
Of course your design is odd.
You should have the functions in the dotted file, not in the calling script.
--
Michael Tosch @ hp : com
| |
| Stephane CHAZELAS 2006-01-13, 10:40 pm |
| 2006-01-10, 22:54(+01), Michael Tosch:
> jrw32982@yahoo.com wrote:
>
> So you would be fine if you could test if a certain function is defined,
> without calling that function.
[...]
You can use "type", but how would that help?
--
Stéphane
| |
| jrw32982@yahoo.com 2006-01-13, 10:40 pm |
| I don't see how the design is odd. The functions are defined in the
file (function library) being dotted. But in the case where these
functions can be run in a different process, there's no need to dot the
file and then call the function; instead I can just call the file as if
it were a script (which in fact it would be). This will work if I can
detect the difference between dotting a function library and calling a
script.
As an example, say the file were called trace.sh, and it's purpose were
to trace (whatever that means) the calling of a shell function or
external command. Trace.sh would define a function called "do_trace"
which takes an argument of a shell function name or an external command
name. Then I can call:
. ./trace.sh
do_trace myfunction # trace a shell function
do_trace /bin/cat ~/.profile # trace an external command
However, if I don't want to trace shell functions, but only external
commands, then it is simpler to just say:
./trace.sh /bin/cat ~/.profile # trace an external command
That would work if trace.sh called
do_trace "$@"
internally trace.sh were being called directly, but not if it were
being dotted as a function library.
| |
| Stephane Chazelas 2006-01-13, 10:40 pm |
| On 10 Jan 2006 15:02:36 -0800, jrw32982@yahoo.com wrote:
> I don't see how the design is odd. The functions are defined in the
> file (function library) being dotted. But in the case where these
> functions can be run in a different process, there's no need to dot the
> file and then call the function; instead I can just call the file as if
> it were a script (which in fact it would be). This will work if I can
> detect the difference between dotting a function library and calling a
> script.
>
> As an example, say the file were called trace.sh, and it's purpose were
> to trace (whatever that means) the calling of a shell function or
> external command. Trace.sh would define a function called "do_trace"
> which takes an argument of a shell function name or an external command
> name. Then I can call:
>
> . ./trace.sh
> do_trace myfunction # trace a shell function
> do_trace /bin/cat ~/.profile # trace an external command
>
> However, if I don't want to trace shell functions, but only external
> commands, then it is simpler to just say:
>
> ./trace.sh /bin/cat ~/.profile # trace an external command
[...]
That's what the autoload and fpath is for in zsh (you may have
something similar in ksh).
the fpath is an array that contains a list of directories where
to find definitions of functions that are elligible for an
autoload. Upon the first call of an autoloaded function, the
corresponding script is loaded and stored in memory as a
function. Those scripts can also be used as scripts:
$ mkdir /tmp/a
$ cat > /tmp/a/f <<EOF
heredoc> #! /bin/zsh
heredoc> echo been there
heredoc> EOF
$ chmod +x /tmp/a/f
$ /tmp/a/f
been there
$ fpath+=(/tmp/a)
$ autoload f
$ which f
f () {
# undefined
builtin autoload -X
}
$ f
been there
$ which f
f () {
echo been there
}
--
Stephane
| |
| jrw32982@yahoo.com 2006-01-13, 10:40 pm |
| zsh's autoload and fpath are nice, handy features, but I don't think
there's an equivalent available in ksh88, unfortunately, which is one
of the platforms I have to support.
Any other tips or pointers to URLs where this kind of thing would be
discussed? I couldn't find it with a google search.
| |
| Chris F.A. Johnson 2006-01-13, 10:40 pm |
| On 2006-01-11, jrw32982@yahoo.com wrote:
> zsh's autoload and fpath are nice, handy features, but I don't think
> there's an equivalent available in ksh88, unfortunately, which is one
> of the platforms I have to support.
>
> Any other tips or pointers to URLs where this kind of thing would be
> discussed? I couldn't find it with a google search.
If you keep your functions in libraries, grouped by function, you
can easily source the necessary ones in any script that needs them.
For example, my function libraries include:
b2k93-funcs ## features specific to bash and ksh93
cgi-funcs ## for CGI scripts
char-funcs ## work on individual characters
conversion-funcs ## metric and other conversions
currency-funcs ## working with dolars and cents
cv-funcs ## Crossword manipulation functions
date-funcs ## Date arithmetic, etc
db-funcs ## Database functions
filename-funcs ## Working with and fixing filenames
funcs ## Misc funcs loaded in .bashrc
html-funcs ## Extract info from HTML files
math-funcs ## Misc. math funcs, incl floating point
mfilter_funcs ## POP3 retrieval and filtering
path-funcs ## Manipulate the PATH variable
screen-funcs ## Screen manipulation functions
standard-funcs ## Misc., used in many scripts
string-funcs ## Manipulate strings
Most of these will work in any POSIX shell, including ksh88.
--
Chris F.A. Johnson, author | <http://cfaj.freeshell.org>
Shell Scripting Recipes: | My code in this post, if any,
A Problem-Solution Approach | is released under the
2005, Apress | GNU General Public Licence
| |
| Kevin Collins 2006-01-13, 10:40 pm |
| In article <1136997628.680427.309400@g14g2000cwa.googlegroups.com>,
jrw32982@yahoo.com wrote:
> zsh's autoload and fpath are nice, handy features, but I don't think
> there's an equivalent available in ksh88, unfortunately, which is one
> of the platforms I have to support.
>
> Any other tips or pointers to URLs where this kind of thing would be
> discussed? I couldn't find it with a google search.
Please post some relevant text when replying to a post...
Yes, they are. See 'man ksh'. The 'autoload' command is "standard" ksh alias:
autoload='typeset -fu'
and you'll want to learn about the FPATH variable. It is not an array like zsh,
but a PATH-like variable for the same purpose.
I use them all the time...
Kevin
--
Unix Guy Consulting, LLC
Unix and Linux Automation, Shell, PERL and CGI scripting
http://www.unix-guy.com
| |
| jrw32982@yahoo.com 2006-01-13, 10:40 pm |
|
Kevin Collins wrote:
> In article <1136997628.680427.309400@g14g2000cwa.googlegroups.com>,
> jrw32982@yahoo.com wrote:
>
> Please post some relevant text when replying to a post...
Sorry. Google's default reply button doesn't give any context. I'll
use the Show Options button to show the context.
> Yes, they are. See 'man ksh'. The 'autoload' command is "standard" ksh alias
You're right. By adding some infrastructure to the calling script
(setting FPATH, calling autoload) I could accomplish what I'm trying to
do. I'll look into it.
However, back to the original question: is there any way of
distinguishing, within a script/file, when it's being dotted from when
it's just being run in a separate process?
-- John
| |
| Stephane CHAZELAS 2006-01-13, 10:40 pm |
| 2006-01-11, 14:29(-08), jrw32982@yahoo.com:
[...]
> However, back to the original question: is there any way of
> distinguishing, within a script/file, when it's being dotted from when
> it's just being run in a separate process?
[...]
No standard way. As I said, there are shell specific ones such
as the BASH_SOURCE, or the behavior that bash's "return" that
differs from one case to another.
Or you can use the sha-bang as described in one of my other
mails.
--
Stephane
| |
| Dan Mercer 2006-01-13, 10:40 pm |
|
<jrw32982@yahoo.com> wrote in message news:1136923043.005859.37520@z14g2000cwz.googlegroups.com...
: I believe I can accomplish this by comparing the value of $0 with the
: name of the file. $0 appears to be the calling script if a file is
: being dotted or the file itself if it is being run directly. But what
: if I don't know (or don't want to hardcode) the name of the file that
: contains the code being run? Is there a *direct* way of telling in ksh
: or bash that code is being run from a dotted file rather than from a
: file being executed directly by the interpreter?
:
: In other words, can you distinguish the following two cases, without
: using the string "myfile"?
:
: . ./myfile
: ./myfile
:
: -- John Wiersba
:
In a sourced file the value of $_ will not be changed
by the execution of any commands, for instance, the
nop command ":". So:
#!/usr/bin/ksh
_old_=$_
: new${_old_}
if [[ $_ = "$_old_" ]]
then
print "File was sourced"
else
print "File was executed"
fi
All bets are off if you get to more complicated arrangements,
like files executed by sourced files without a shebang. You
can investigate that on your own.
As for FPATH and autoload, to the best of my knowledge they
are ksh inventions. I don't know how autoload works under
zsh, but under ksh it merely marks a name as being an
undefined function. The function isn't loaded (defined)
until actually called the first time. Indeed, it needn't
exist at all. Autoload is primarily used when there is a
possibility that there may be a conflict between a function
name and the name of a command. It directs the shell to
ONLY look for a function by that name. If one does not exist
or is not in the FPATH, an error returns.
In ksh88 it's not very well integrated. If you actually have an
executable with the same name and enter "type name" which is
actually "whence -v name" it will return the path of the executable
name rather than "undefined function" as it does in ksh93.
Trying to "unset -f" it is useless in ksh88 as well. Instead
you have to create a minimal definition, then unset it:
$ name() { :; }
$ unset -f name
For more useful information, please Google "Fun with Functions".
Dan Mercer
| |
| Dan Mercer 2006-01-13, 10:40 pm |
|
"Stephane CHAZELAS" <this.address@is.invalid> wrote in message news:slrndsb2fk.fi8.stephane.chazelas@spam.is.invalid...
: 2006-01-11, 14:29(-08), jrw32982@yahoo.com:
: [...]
: > However, back to the original question: is there any way of
: > distinguishing, within a script/file, when it's being dotted from when
: > it's just being run in a separate process?
: [...]
:
: No standard way. As I said, there are shell specific ones such
: as the BASH_SOURCE, or the behavior that bash's "return" that
: differs from one case to another.
or ksh's usage of $_.
Dan Mercer
:
: Or you can use the sha-bang as described in one of my other
: mails.
:
: --
: Stephane
| |
| Stephane CHAZELAS 2006-01-13, 10:40 pm |
| 2006-01-12, 01:20(+00), Dan Mercer:
[...]
> In a sourced file the value of $_ will not be changed
> by the execution of any commands, for instance, the
> nop command ":". So:
>
> #!/usr/bin/ksh
> _old_=$_
> : new${_old_}
> if [[ $_ = "$_old_" ]]
> then
> print "File was sourced"
> else
> print "File was executed"
> fi
[...]
That would depend on the version of ksh. I don't get it here with
pdksh. And I can't see anything like that documented in
http://www.cs.princeton.edu/~jlk/ko.../doc/man93.html
(who said ksh was an open language ;)).
_
Initially, the value of _ is an absolute pathname of the
shell or script being executed as passed in the
environment. Subsequently it is assigned the last argument
of the previous command. This parameter is not set for
commands which are asynchronous. This parameter is also
used to hold the name of the matching MAIL file when
checking for mail.
Which is a misleading statement. The _ is an absolute pathname
of the shell or script only if the process that started that
shell or script followed that convention. That is generally not
true unless that process was a POSIX shell.
--
Stéphane
| |
| Dan Mercer 2006-01-13, 10:40 pm |
|
"Stephane CHAZELAS" <this.address@is.invalid> wrote in message news:slrndsc3ai.4sg.stephane.chazelas@spam.is.invalid...
: 2006-01-12, 01:20(+00), Dan Mercer:
: [...]
: > In a sourced file the value of $_ will not be changed
: > by the execution of any commands, for instance, the
: > nop command ":". So:
: >
: > #!/usr/bin/ksh
: > _old_=$_
: > : new${_old_}
: > if [[ $_ = "$_old_" ]]
: > then
: > print "File was sourced"
: > else
: > print "File was executed"
: > fi
: [...]
:
: That would depend on the version of ksh. I don't get it here with
: pdksh.
pdksh is not ksh (and not in the way GNU is not UNIX).
I lost track of all the inconsistencies I've found between
pdksh and the real McCoy.
: And I can't see anything like that documented in
: http://www.cs.princeton.edu/~jlk/ko.../doc/man93.html
:
: (who said ksh was an open language ;)).
:
: _
: Initially, the value of _ is an absolute pathname of the
: shell or script being executed as passed in the
: environment. Subsequently it is assigned the last argument
: of the previous command. This parameter is not set for
: commands which are asynchronous. This parameter is also
: used to hold the name of the matching MAIL file when
: checking for mail.
I believe dot commands, function calls, and backgrounded commands
are all considered asynchronous commands.
:
: Which is a misleading statement. The _ is an absolute pathname
: of the shell or script only if the process that started that
: shell or script followed that convention.
If the script has a shebang and is called by it's name, the
full path of the script will be in $_. If called by
ksh script
the full path of ksh will be in $_. Which is exactly what the above
statement asserts. If the file does not have a shebang, $_ will
contain whatever minimal pathing is required to find the file. If in
the current directory, just the name. If in a child directory
in the path, child/name. If in a foreign path, the full pathname.
However, if explicitly pathed, $_ will contain the explicit path
named, e.g. ./name
If sourced:
. script
then $_ will contain whatever was in $_ PRIOR to the dot command.
$_ will be updated AFTER the dot command has completed.
That is generally not
: true unless that process was a POSIX shell.
When I tested with csh, $_ was set to /bin/ksh.
Dan Mercer
:
: --
: Stiphane
| |
| Stephane CHAZELAS 2006-01-13, 10:40 pm |
| 2006-01-13, 01:11(+00), Dan Mercer:
[...]
> : That would depend on the version of ksh. I don't get it here with
> : pdksh.
>
> pdksh is not ksh (and not in the way GNU is not UNIX).
> I lost track of all the inconsistencies I've found between
> pdksh and the real McCoy.
I tend to consider it as the real one as it's the only one you
can predict how it will behaves as the other one is poorly
documented, and the source code is not available.
[...]
> : _
> : Initially, the value of _ is an absolute pathname of the
> : shell or script being executed as passed in the
> : environment. Subsequently it is assigned the last argument
> : of the previous command. This parameter is not set for
> : commands which are asynchronous. This parameter is also
> : used to hold the name of the matching MAIL file when
> : checking for mail.
>
> I believe dot commands, function calls, and backgrounded commands
> are all considered asynchronous commands.
No, it's documented in ksh93 man page what an asynchronous
command is. A function call and a dot command are synchronous.
>
> :
> : Which is a misleading statement. The _ is an absolute pathname
> : of the shell or script only if the process that started that
> : shell or script followed that convention.
>
> If the script has a shebang and is called by it's name, the
> full path of the script will be in $_. If called by
No, it will be only if whatever process called that script put
that definition of _ in the envp argument of the execve system
call. I initially thought it was a POSIX requirement, but it
doesn't even seem to be true.
$ cat a
#! /usr/bin/ksh -
echo $_
~$ ./a
/home/chazelas/./a
~$ env ./a
/usr/bin/env
My shell (zsh) did, env didn't
--
Stéphane
| |
| Stephane CHAZELAS 2006-01-14, 7:48 am |
| 2006-01-13, 23:17(+00), Dan Mercer:
[...]
> : No, it's documented in ksh93 man page what an asynchronous
> : command is. A function call and a dot command are synchronous.
>
> I missed that. Reference? It does mention backgrounded calls
> as being asynchronous, but I didn't think it limited it to that.
>
> Function calls won't set $_ other than explicitly (found that out the
> hard way).
& starts an asynchronous command. That's all.
What else would you want to be asynchronous. In which way a
function call would be asynchronous?
[...]
> : No, it will be only if whatever process called that script put
> : that definition of _ in the envp argument of the execve system
> : call. I initially thought it was a POSIX requirement, but it
> : doesn't even seem to be true.
>
> IOW, if called by the shell. To the KSH guys, ksh is the shell, the
> ONLY shell. That's all they run, period.
??? Don't they call xargs, find (-exec), env, awk (system()).
I'd bet there are many utilities in the at&t packages that do as
well (tw comes to mind for instance).
> :
> : $ cat a
> : #! /usr/bin/ksh -
> : echo $_
> : ~$ ./a
> : /home/chazelas/./a
> : ~$ env ./a
> : /usr/bin/env
> :
> :
> : My shell (zsh) did, env didn't
>
> env exec'd a, it didn't call it (fork and exec). Still seems
> consistent to me.
Then replace env with xargs, find or awk, or any command that
calls system(3) (though depending on the shell it calls,
system(3) may also set $_) or a fork+exec.
> BTW, which ksh? pd, 88 or 93?
Any shell.
--
Stéphane
| |
| John Bianchi 2006-01-29, 9:31 pm |
| Well, with the newer versions of BASH there is a variable called:
$BASH_SOURCE
which will contain the source file name which you can check inside the
source file (check $0 against $BASH_SOURCE maybe?)
Hope that helps as I've been looking for an answer to this for over 3
years (since before I started using RH 7.0). I had a few scenarios for
this usage but have long since forgotten what and must have given up and
hacked around the problem.
Just installed FC4 and researched this qestion.
jrw32982@yahoo.com wrote:
> I believe I can accomplish this by comparing the value of $0 with the
> name of the file. $0 appears to be the calling script if a file is
> being dotted or the file itself if it is being run directly. But what
> if I don't know (or don't want to hardcode) the name of the file that
> contains the code being run? Is there a *direct* way of telling in ksh
> or bash that code is being run from a dotted file rather than from a
> file being executed directly by the interpreter?
>
> In other words, can you distinguish the following two cases, without
> using the string "myfile"?
>
> . ./myfile
> ./myfile
>
> -- John Wiersba
>
|
|
|
|
|