How to emulate the Unix command "which"

Discussion in 'Perl Misc' started by Leon Nabot, Aug 19, 2005.

  1. Leon Nabot

    Leon Nabot Guest

    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
    Leon Nabot, Aug 19, 2005
    #1
    1. Advertising

  2. Leon Nabot

    Anno Siegel Guest

    Leon Nabot <nabotleon@hotmail_N0_SPAMZ.com> wrote in comp.lang.perl.misc:
    > 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
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Aug 19, 2005
    #2
    1. Advertising

  3. Leon Nabot

    Guest

    Leon Nabot <nabotleon@hotmail_n0_spamz.com> wrote:
    > 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
    , Aug 19, 2005
    #3
  4. Leon Nabot

    Guest

    Leon Nabot <nabotleon@hotmail_n0_spamz.com> wrote:
    > 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
    , Aug 19, 2005
    #4
  5. [A complimentary Cc of this posting was sent to

    <>], who wrote in article <>:
    > Leon Nabot <nabotleon@hotmail_n0_spamz.com> wrote:
    > > 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" }


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

    Hope this helps,
    Ilya
    Ilya Zakharevich, Aug 19, 2005
    #5
  6. Leon Nabot

    Leon Nabot Guest

    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


    > 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, .
    Leon Nabot, Aug 19, 2005
    #6
  7. Leon Nabot <nabotleon@hotmail_N0_SPAMZ.com> wrote in news:4305ce66$0
    $4171$:

    [ 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:

    > wrote in
    > news::
    >
    >> A quick way for a single command is:
    >>
    >> foreach (split(/:/,$ENV{PATH})) { print "Found $_/rsh\n" if -x
    >> "$_/rsh" }


    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

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Aug 19, 2005
    #7
  8. Leon Nabot

    Guest

    Leon Nabot <nabotleon@hotmail_n0_spamz.com> wrote:
    >
    > 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.

    --
    Chris Green
    , Aug 19, 2005
    #8
  9. Leon Nabot

    Guest

    A. Sinan Unur <> wrote:
    >>> A quick way for a single command is:


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


    > 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;


    Why do you use this form rather than a normal variable?

    Axel
    , Aug 19, 2005
    #9
  10. wrote in
    news:9GkNe.6860$:

    > A. Sinan Unur <> wrote:
    >>>> A quick way for a single command is:

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

    >
    >> 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;

    >
    > 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

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Aug 19, 2005
    #10
  11. Leon Nabot

    Guest

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


    No thanks. This is usenet.


    >> 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.


    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
    , Aug 19, 2005
    #11
  12. Ilya Zakharevich wrote:
    > [A complimentary Cc of this posting was sent to
    >
    > <>], who wrote in article <>:
    >>Leon Nabot <nabotleon@hotmail_n0_spamz.com> wrote:
    >>>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" }

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


    Or:

    use Env '@PATH';


    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Aug 19, 2005
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alvin Bruney [MVP]

    Re: emulate Win. app lookup in ASP.NET

    Alvin Bruney [MVP], Feb 14, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    387
    Steve Bywaters
    Feb 16, 2004
  2. Replies:
    4
    Views:
    1,697
    Terry Hancock
    Apr 23, 2005
  3. Kevin Wan
    Replies:
    0
    Views:
    385
    Kevin Wan
    Jan 16, 2007
  4. Dan Bikle
    Replies:
    3
    Views:
    130
  5. Alain Star
    Replies:
    7
    Views:
    162
    Tad McClellan
    Jan 18, 2005
Loading...

Share This Page