Bug 133808 - 'which' doesn't follow the movement of executable
Summary: 'which' doesn't follow the movement of executable
Status: RESOLVED FIXED
Alias: None
Product: SUSE LINUX 10.0
Classification: openSUSE
Component: Other (show other bugs)
Version: unspecified
Hardware: x86 Other
: P5 - None : Minor
Target Milestone: ---
Assignee: Dr. Werner Fink
QA Contact: E-mail List
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-15 09:38 UTC by Nick Lee
Modified: 2005-11-21 15:56 UTC (History)
0 users

See Also:
Found By: Other
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Lee 2005-11-15 09:38:50 UTC
1. Login as root.
2. Unzip 'tidy' into /root/bin
3. Do a 'which tidy' -> shows /root/bin/tidy
4. Execute tidy no problem
5. Do a 'mv bin/tidy /usr/bin'
6. Do a 'which tidy' again -> still shows /root/bin/tidy
7. Try to execute tidy by typing just 'tidy'
    -> shows 'bash: /root/bin/tidy: No such file or directory'

Note: /usr/bin is in my path. I can execute other executables in /usr/bin no problem (just by typing the file name only).
Comment 1 Michael Gross 2005-11-15 13:37:26 UTC
I was not able to reproduce this bug. What release of SL 10.0 did you use? Works fine with the final.
Comment 2 Nick Lee 2005-11-16 03:56:01 UTC
I downloaded SL from:
  http://www.opensuse.org/Released_Version

I assume that's the "final" version. And yes, I'm sure it's SL 10.0

By the way, I found that the path to the executable only becomes 'fixed' after you run the executable once. That is, if you move the executable around without ever running it, 'which' always shows the correct path. It's only after you run it the path gets 'cached' somehow. Try moving it AFTER you execute the file once, hopefully you can reproduce the bug that way.
Comment 3 Michael Gross 2005-11-17 16:34:16 UTC
Yes. That is so. The problem here is that the shell keeps a cache about the recently executed commands so that it needn't search the whole path over and over again. This will only affect the builtin `type', though. The external command will always do a real search:

mgross@targ:~> type -all which
which is aliased to `type -p'
which is /usr/bin/which

The alias will have the preference before the external program /usr/bin/which here. Typing only `which' calls `type -p` therefore.

This cache of the bash can be shown with `hash' and it can be emptied with `hash -r` after which a real search is done. Alternatively the external which can be called explicitly (stating the whole path or using quotes, which will do the same thing here.

Here are the commands I tested this with for a better understanding:

targ:~ # echo -e '#!/usr/bin/perl\n' > /usr/bin/testfile.pl && chmod +x /usr/bin
/testfile.pl
targ:~ # which testfile.pl
/usr/bin/testfile.pl
targ:~ # "which" testfile.pl
/usr/bin/testfile.pl
targ:~ # testfile.pl
targ:~ # mv /usr/bin/testfile.pl /bin
targ:~ # which testfile.pl
/usr/bin/testfile.pl
targ:~ # "which" testfile.pl
/bin/testfile.pl
targ:~ # hash
hits    command
   2    /usr/bin/which
   1    /sbin/preload
   2    /bin/chmod
   2    /usr/bin/testfile.pl
   2    /bin/mv
   2    /usr/sbin/grub
   1    /usr/bin/whoami
   3    /usr/bin/vi
targ:~ # hash -r
targ:~ # which testfile.pl
/bin/testfile.pl
targ:~ # "which" testfile.pl
/bin/testfile.pl

This setup (alias goes before external) is a bash-behaviour that cannot be changed AFAIK. One would have to remove the alias or state exactly what shall be executed (as seen above). This is no bug, it's the same thing in 9.3.

You're free to change this, of course.
Werner: Can you provide any comment here? Maby we should change the default setup here? Please decide what should be done.
Comment 4 Michael Gross 2005-11-17 16:45:11 UTC
Just a thought: Shouldn't type at least verify the existance of the file before using the cached value? This wouldn't take much time and would be more sound I think. A patch would be in order.
Comment 5 Dr. Werner Fink 2005-11-17 17:12:07 UTC
I'd like not to change the default, any admin
should be able to call `rehash' or `hash -r'.

On the other side, the bash chould check the
existence of a program in path and if not
found run a rehash ... but this may cause
trouble in a NFS environment if the NFS server
is temporary not reachable.
Comment 6 Nick Lee 2005-11-18 03:43:42 UTC
Thanks Michael. I'll just remove the alias then.
Comment 7 Dr. Werner Fink 2005-11-21 13:59:13 UTC
Using now a shell function which checks the existence of the
file and if required runs `has -r'.
Comment 8 Michael Gross 2005-11-21 15:56:46 UTC
Nick: You're welcome. And thanks to Werner.