Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

[OT] 'perl' is not the 'perl' reported by 'which perl'

by syphilis (Archbishop)
on Aug 21, 2020 at 14:06 UTC ( [id://11120959]=perlquestion: print w/replies, xml ) Need Help??

syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm assuming this post is OT.
I expect that the problem is explained in terms of the Linux operating system.
I run:
$ which perl /home/sisyphus-sis/blead-5.33.1-m64-ld/bin/perl
and I therefore assume that perl and /home/sisyphus-sis/blead-5.33.1-m64-ld/bin/perl will be one and the same ... but they're not.
$ /home/sisyphus-sis/blead-5.33.1-m64-ld/bin/perl -le 'print $];' 5.033001 $ perl -le 'print $];' 5.014002
How is this explained ?
It seems to happen when, having specified a $PATH that contains perl-5.014002 as the first perl in $PATH, I then position a different perl (5.33.1) ahead of perl-5.014002 in $PATH (without actually altering $PATH).
So, I'm thinking it's some sort of caching bug in my Debian wheezy system. (I haven't yet checked to see whether Ubuntu-18.04 does the same thing.)

Is it buggy behaviour ? ... or is there some clever legalese that justifies it ?

Cheers,
Rob

PS
To elaborate, I built 5.33.1 into the above-specified location, and prepended that above-specified location (ie /home/sisyphus-sis/blead-5.33.1-m64-ld/bin) to $PATH, but both perl -V and which perl reported the system perl (5.014002), which is further along in $PATH.

This happened because I forgot to build perl-5.33.1 with the -Uversiononly configure option, and the perl executable was in fact named perl5.33.1
So I created a copy of perl5.33.1 named perl and, while which perl now specifies this copy of perl5.33.1, if I invoke perl it's still the system perl that is executed.
Seems insane to me.

Replies are listed 'Best First'.
Re: [OT] 'perl' is not the 'perl' reported by 'which perl'
by jo37 (Deacon) on Aug 21, 2020 at 15:01 UTC

    This might be caused by bash's hashing. Like this:

    jo@bear$ PATH=/home/jo/bin:/usr/local/bin:/usr/bin:/bin jo@bear$ cat <<EOF >tellme.sh > #!/bin/bash > echo this is tellme.sh from /usr/local/bin > EOF jo@bear$ chmod +x tellme.sh jo@bear$ sudo cp tellme.sh /usr/local/bin jo@bear$ which tellme.sh /usr/local/bin/tellme.sh jo@bear$ tellme.sh this is tellme.sh from /usr/local/bin jo@bear$ cat <<EOF >tellme.sh > #!/bin/bash > echo this is tellme.sh from ~/bin EOF jo@bear$ cp tellme.sh bin jo@bear$ which tellme.sh /home/jo/bin/tellme.sh jo@bear$ tellme.sh this is tellme.sh from /usr/local/bin jo@bear$ hash -d tellme.sh jo@bear$ tellme.sh this is tellme.sh from /home/jo/bin

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
Re: [OT] 'perl' is not the 'perl' reported by 'which perl'
by LanX (Saint) on Aug 21, 2020 at 14:16 UTC
    Did you check if there are any aliases in bash?

    What happens if you try to call Perl from Perl via qx?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      alias is a good thing to check (alias -p). Similarly, a bash function perl defined in your environment could cause a similar effect and are not reported by alias -p. If that's not expected and it exists, then something fish is happening for sure. I don't know off the top of my head how to see what bash functions are currently defined. I believe which is aware of aliases, not sure about bash functions. Does which which what you expect? Maybe try it with the absolute path.
Re: [OT] 'perl' is not the 'perl' reported by 'which perl'
by syphilis (Archbishop) on Aug 22, 2020 at 05:36 UTC
    On Ubuntu-18.04.5 the manual (man which) states:
    DESCRIPTION which returns the pathnames of the files (or links) which would be exe +- cuted in the current environment, had its arguments been given as com +- mands in a strictly POSIX-conformant shell. It does this by searchin +g the PATH for executable files matching the names of the arguments. I +t does not canonicalize path names.
    I assume that I have a POSIX-conformant shell:
    $ echo $SHELL /bin/bash
    I don't know what "It does not canonicalize path names" means. Is that relevant to this issue ?

    Pretty clearly, the manual tells me that which perl returns the path of the perl that will be executed when, in my bash shell, I enter a command beginning with the word "perl".
    Just as clearly, that assertion is false in my particular situation.
    Here's a demo, starting with a freshly opened bash shell:
    $ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/game +s:/usr/local/games:/snap/bin $ which perl /usr/bin/perl $ perl -le 'print $];' 5.026001 $ /usr/bin/perl -le 'print $];' 5.026001 # Select another perl, and hide the # perl executable by renaming it $ mv ~/perl528-d/bin/perl ~/perl528-d/bin/perl_hide # Prepend the location of that # "hidden" perl to $PATH $ export PATH=~/perl528-d/bin:$PATH # That change to $PATH clears the cache, # so run a perl command that will again # set the cached perl to /usr/bin/perl. # The problem does not arise if this # step is omitted. $ perl -le 'print $];' 5.026001 # Make the hidden perl visible again $ mv ~/perl528-d/bin/perl_hide ~/perl528-d/bin/perl $ which perl /home/sisyphus/perl528-d/bin/perl $ /home/sisyphus/perl528-d/bin/perl -le 'print $];' 5.028000 $ perl -le 'print $];' 5.026001
    The only thing happening that's "wrong" is that final output. Everything else is sane and as expected.

    Of course, in my original case, I didn't run a command aimed at caching perl to /usr/bin/perl. (I just ran perl -V, expecting to see the configuration of the newly installed 5.33.1 - and getting the configuration of the system perl instead.)
    And I didn't begin by renaming the "perl" executable to something else.
    It was installed already named as something else (namely "perl5.33.1").
    All I did was to rename "perl5.33.1" to "perl" - which would have been sufficient if "perl" was not by then cached as "/usr/bin/perl"

    I do think the "which" documentation is way too glib.
    Sure, it specifies the way that "which" determines the pathname of its argument(s), but it should not be unconditionally asserting that this will match the pathname used when that argument is given as a command in a strictly POSIX-conformant shell. That is (demonstrably) not always true - and the documentation should at least point this out.

    Cheers,
    Rob

    PS
    Following on from where I left off the above one liners, and just to demonstrate clearly that a change to $PATH is enough to reset the cache:
    $ perl -le 'print $];' 5.026001 $ export PATH=~/nonexistent:$PATH $ perl -le 'print $];' 5.028000
    But I doubt that needed to be demonstrated, anyway ;-)

      You seem to have figured out that the issue here is bash's hashing. You can delete the entire hash with hash -r or just the one path with hash -d perl.

      which(1) can be pretty squirrelly and and should be avoided. Bash has the type builtin which will display aliases as well as executable files. To get the documentation on bash builtins, you can use the help builtin. e.g. help type

      Canonical names aren't an issue here but realpath is how you get one.

        which(1) can be pretty squirrelly and and should be avoided.

        Yes - but the main problem with it is simply that its documentation misses out on some crucial detail.
        If that documentation (as provided by man which) mentioned that it didn't always provide what the current documentation (as provided by man which) states that it does, then you could not be critical of it.
        Even better if that documentation recommended using "type" instead.
        But I find it a bit laughable that you have to do type perl in order to get the information that man which falsely claims as being always returned by which perl

        Anyway ... thanks (as always) to all respondents for their contributions.
        And, in future, whenever I see anyone on perlmonks respond to a question with "which perl ?" I'll personally set them straight ;-)

        Cheers,
        Rob
A reply falls below the community's threshold of quality. You may see it by logging in.
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11120959]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-19 09:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found