Re: Get My Own Name
by Abigail-II (Bishop) on Feb 04, 2004 at 15:59 UTC
|
Ignore the people who come with $0. If people can
have renamed the program, they could have given it an additional link as well, and no $0 is going to
protect you against that. Besides, what if people rename
the program after it was started?
Don't rely on the file, use the inode number instead.
To get the inode number of your program, add __DATA__
to the end of it, and use:
my $inode_number = (stat DATA) [1]; # And not fileno!
Abigail | [reply] [d/l] |
|
|
To expand on what Abigail-II points out here, once you
have the inode number of your script, you can then test
the inode numbers in a similar manner for each file
you are operating on and test that they are not equal.
Just thought I'd clarify that point...
I like that solution!
Peter L. Berghold -- Unix Professional Peter at Berghold dot Net |
| |
Dog trainer, dog agility exhibitor, brewer of
fine Belgian style ales. Happiness is a warm, tired, contented dog curled up at your side and
a good Belgian ale in your chalice. |
| [reply] |
|
|
$ ls -i ./foo /tmp/foo
1808983 ./foo@ 228688 /tmp/foo
$ perl -le 'print( (stat "./foo")[1] )'
228688
So the truly paranoid might use join("|",(stat DATA)[0,1]).
| [reply] [d/l] [select] |
|
|
The original query did not specify what OS they were on.
inode is meaningless on win32, so this suggestion is not portable.
Sorry - I do not have a better original suggestion - I would settle for parsing $0 on win32.
"When you are faced with a dilemma, might as well make dilemmanade.
"
| [reply] |
Re: Get My Own Name
by blue_cowdawg (Monsignor) on Feb 04, 2004 at 15:48 UTC
|
Yep. At first blush if you use $0 that will
give you the name of the script being executed. But be
careful. Let me show you a few case studies.
Invoking a script via the interpreter
Consider the following very simple script:
#!/usr/bin/perl -w
print $0,"\n";
If I invoke it as
perl testzero.pl
sure
enough it prints testzero.pl to stdout.
Let's add a wrinkle! If I execute it as
perl /home/peter/testzero.pl then then
entire path name will be printed to stdout.
chmod'ed script
If I do a chmod 755 testzero.pl on my
hapless script (assuming *nix environment here) then I
have a similar problem. Executing
./testzero.pl
will yield ./testzero.pl to stdout and so forth.
In summary, hes you can get the path name of the
script being executed but make sure you understand all
of the implications.
Peter L. Berghold -- Unix Professional Peter at Berghold dot Net |
| |
Dog trainer, dog agility exhibitor, brewer of
fine Belgian style ales. Happiness is a warm, tired, contented dog curled up at your side and
a good Belgian ale in your chalice. |
| [reply] [d/l] [select] |
|
|
There is also the interesting ( althought not relevant to the OP ) case of doing:
perl -e 'print "My name is $0.\n\n";'
which produces: "My name is -e."
--tidiness is the memory loss of environmental mnemonics
| [reply] [d/l] [select] |
|
|
use FindBin;
print $FindBin::Bin, $/;
-- [ e d @ h a l l e y . c c ]
| [reply] [d/l] |
Re: Get My Own Name
by EvdB (Deacon) on Feb 04, 2004 at 15:40 UTC
|
$0 Contains the name of the program being executed.
On some (read: not all) operating systems
assigning to $0 modifies the argument area that
the "ps" program sees. On some platforms you may
have to use special "ps" options or a different
"ps" to see the changes. Modifying the $0 is more
useful as a way of indicating the current program
state than it is for hiding the program you're
running. (Mnemonic: same as sh and ksh.)
Note that there are platform specific limitations
on the the maximum length of $0. In the most
extreme case it may be limited to the space
occupied by the original $0.
In some platforms there may be arbitrary amount of
padding, for example space characters, after the
modified name as shown by "ps". In some platforms
this padding may extend all the way to the
original length of the argument area, no matter
what you do (this is the case for example with
Linux 2.2).
Note for BSD users: setting $0 does not completely
remove "perl" from the ps(1) output. For example,
setting $0 to "foobar" may result in "perl: foobar
(perl)" (whether both the "perl: " prefix and the
" (perl)" suffix are shown depends on your exact
BSD variant and version). This is an operating
system feature, Perl cannot help it.
In multithreaded scripts Perl coordinates the
threads so that any thread may modify its copy of
the $0 and the change becomes visible to ps(1)
(assuming the operating system plays along). Note
that the the view of $0 the other threads have
will not change since they have their own copies
of it.
--tidiness is the memory loss of environmental mnemonics
| [reply] [d/l] [select] |
Re: Get My Own Name
by valdez (Monsignor) on Feb 04, 2004 at 15:41 UTC
|
| [reply] [d/l] |
Re: Get My Own Name
by flyingmoose (Priest) on Feb 04, 2004 at 19:32 UTC
|
given $0 is unreliable and inode theory is not portable, I have to ask (please forgive me) -- just what are you trying to do?
I understand the current problem, but what is the purpose of this script? It may be, for instance, that you can make better choices about what file is a potential target for processing (based on name or contents). You may be able to run this from another path.
This problem seems sort of odd, so I think that warrants an inquiry into the function of the script.
| [reply] |
|
|
Because tar on HP-UX is broken, we have been forced to implement our own work around. Normally, on Solaris at least, you can supply tar with an exclude file. Thus allowing you to avoid tarring up mp3s or your collections of GTK+ themes and backgrounds or what have you.
I wanted to include this functionality in the script because you never can tell when some one is going to pass the script along to a friend but not tell them how to use it properly. Nor did I want to have to hardcode the name of the script since file names can change.
| [reply] |
|
|
| [reply] |
|
|
HP-UX tar is broken? How about GNU tar? It has exclude options
| [reply] |
|
|
That's why God gave us cpio.
Abigail
| [reply] |
Re: Get My Own Name
by archangelq (Novice) on Feb 04, 2004 at 20:02 UTC
|
My suggestion would be to use File::Basename on $0, as it turns out. Example:
use File::Basename;
my $scriptname = basename($0);
Simple and to the point. Then just an
unless(basename($file) eq $scriptname)
{
...
}
in your testing loop, there you go. | [reply] [d/l] [select] |
|
|
use File::Basename;
my ($scriptname, $scriptdir) = fileparse($0);
while($file = shift(@files)){
my($name, $dir) = fileparse($file);
unless($dir eq $scriptdir and $scriptname eq $name){
...
}
}
Note: This code is drawn from memory, and not directly tested. I really should take the lead of some of the monks and just put a disclaimer in my sig. OTOH, I did check the perl docs to be sure I hadn't typoed names, and sure enough, I had, so at least it's not typo-rific. | [reply] [d/l] |