How to emulate the Unix command "which"

L

Leon Nabot

Hello,

I try to find a quick solution to find onto the PATH where is located an
executable as "which" do.

I have tried to use the "which" command into a pipe or backtick but the
returns are not the same in all Unixes, in particular if the searched
command is aliased, .

Anyone would know an easy way to do this ?

For the moment the only solution seems to write a module which browse
each directory of the PATH searching the file.

We need a solution that works only with the defaults functions/libs of a
Perl 5.005 (And up)

Rgds.

Léo
 
A

Anno Siegel

Leon Nabot said:
Hello,

I try to find a quick solution to find onto the PATH where is located an
executable as "which" do.

I have tried to use the "which" command into a pipe or backtick but the
returns are not the same in all Unixes, in particular if the searched
command is aliased, .

If it reports aliases it isn't the external /usr/bin/which (or whatever),
but the shell builtin. Aliases are in she shell's workspace, external
programs don't know about them.

So you have essentially three choices of which "which" to use: The
external one, the one in the csh family and the one in the sh family.
Anyone would know an easy way to do this ?

It isn't hard, but there is no trick that makes it particularly easy.
Walk through the $PATH directories and look for files with the right
name that are executable by the invocant. You can't report aliases
that way.

Alternatively you can use the external "which", or one of the shell's
builtins and post-process the output depending on the OS you're on.
The shell builtins may be more regular than it appears when you take
care to use the same shell everywhere.

Anno
 
C

chris-usenet

Leon Nabot said:
I try to find a quick solution to find onto the PATH where is located an
executable as "which" do.
For the moment the only solution seems to write a module which browse
each directory of the PATH searching the file.

A quick way for a single command is:

foreach (split(/:/,$ENV{PATH})) { print "Found $_/rsh\n" if -x "$_/rsh" }


Or, if you want a fancier version:

my %what = (
ls => undef,
rsh => undef,
rfc => undef,
);

foreach my $path (reverse split (/:/, $ENV{PATH})) {
$path = '.' if $path eq '';
foreach my $cmd (keys %what) {
my $file = "$path/$cmd";
$what{$cmd} = $file if -x $file;
}
}

use Data::Dumper;
print Dumper (\%what), ".\n";

Chris
 
A

axel

Leon Nabot said:
I try to find a quick solution to find onto the PATH where is located an
executable as "which" do.
I have tried to use the "which" command into a pipe or backtick but the
returns are not the same in all Unixes, in particular if the searched
command is aliased, .

How are you specifying 'which' - in other words, which 'which' are
you using. It can appear as a shell built in command in tcsh which
will pick up aliases. However the standalone version (maybe
/usr/bin/which depending on your system) will not pick up aliases.

Axel
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to

A quick way for a single command is:

foreach (split(/:/,$ENV{PATH})) { print "Found $_/rsh\n" if -x "$_/rsh" }

Splitting PATH on /:/ is wrong. Use $Config{path_sep} instead.

Hope this helps,
Ilya
 
L

Leon Nabot

Thank's to all.

The solution suggested by Chris is just good for me (One line of code)

I give up the use of the system "which" command because it seems that on
Solaris even the standalone version reports the alias (When in Linux and
HPUX it reports the real path)

Rgds.

Léo
 
A

A. Sinan Unur

[email protected]:

[ Please do not top-post.
Please quote the article you are replying to.
]
The solution suggested by Chris is just good for me (One line of code)

Is that really a good criterion?

Let's review the solution:
(e-mail address removed) wrote in

This, IMHO, is needlessly platform dependent. One can make this fairly
portable by using File::Spec:

#!/usr/bin/perl

use strict;
use warnings;

use File::Spec::Functions qw'catfile path';

use constant LOOK_FOR => shift;

unless( LOOK_FOR ) {
die "Please provide the name of the command you want to find\n";
}

my @path = path;

for my $dir ( @path ) {
my $fn = catfile $dir, LOOK_FOR;
print "Found $fn\n" if -x $fn;
}

__END__

D:\Home\asu1\UseNet\clpmisc> mywhich perl.exe
Found C:\opt\Perl\bin\perl.exe
Found C:\opt\cygwin\bin\perl.exe

Sinan
 
U

usenet

Leon Nabot said:
Thank's to all.

The solution suggested by Chris is just good for me (One line of code)

I give up the use of the system "which" command because it seems that on
Solaris even the standalone version reports the alias (When in Linux and
HPUX it reports the real path)
Yes, I think the standalone 'which' on Solaris does wierd things like
looking at what shell you are running and then trying to parse the
relevant files to find aliases as well as actual executables on the
PATH.
 
A

A. Sinan Unur

(e-mail address removed) wrote in
Why do you use this form rather than a normal variable?

For variety :)

Actually, to match the way the command line argument is used in the
script: It is a value given from the outside which the script will not
modify.

Sinan
 
C

chris-usenet

Ilya Zakharevich said:
[A complimentary Cc of this posting was sent to <[email protected]>]

No thanks. This is usenet.

Splitting PATH on /:/ is wrong. Use $Config{path_sep} instead.

I did say it was a quick way.

To anyone else reading this thread, don't forget you'll need "use Config"
to populate the %Config hash values.

Chris
 
J

John W. Krahn

Ilya said:
[A complimentary Cc of this posting was sent to

A quick way for a single command is:

foreach (split(/:/,$ENV{PATH})) { print "Found $_/rsh\n" if -x "$_/rsh" }

Splitting PATH on /:/ is wrong. Use $Config{path_sep} instead.

Or:

use Env '@PATH';


John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top