Ok, let me try to explain myself as clearly as I can.
Here are some commands I have just tried from a BASH shell in my Manjaro PC Konsole:
You see what is in my PATH and that /usr/local/sbin comes before /usr/bin and that I have two binaries called parted each in two different locations.
/usr/local/sbin/parted is version 3.66
/usr/bin/parted is version 3.6.
[flex@thinkpad ~]$ echo $PATH
/home/flex/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/usr/lib/rustup/bin:/var/lib/snapd/snap/bin
[flex@thinkpad ~]$ which parted -a
/usr/local/sbin/parted
/usr/bin/parted
[flex@thinkpad ~]$ /usr/local/sbin/parted -v
parted (GNU parted) 3.6.6-c5bd-dirty
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by <http://git.debian.org/?p=parted/parted.git;a=blob_plain;f=AUTHORS>.
[flex@thinkpad ~]$ /usr/bin/parted -v
parted (GNU parted) 3.6
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by <http://git.debian.org/?p=parted/parted.git;a=blob_plain;f=AUTHORS>.
[flex@thinkpad ~]$ parted -v
parted (GNU parted) 3.6.6-c5bd-dirty
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by <http://git.debian.org/?p=parted/parted.git;a=blob_plain;f=AUTHORS>.
[flex@thinkpad ~]$
[flex@thinkpad ~]$ sudo mv /usr/local/sbin/parted /usr/local/sbin/parted-patched
[flex@thinkpad ~]$
[flex@thinkpad ~]$ which parted -a
/usr/bin/parted
[flex@thinkpad ~]$ parted -v
bash: /usr/local/sbin/parted: No such file or directory
[flex@thinkpad ~]$
I use the mv command to rename the parted binary in /usr/local/sbin to parted-patched. So I now only have one binary in my system called parted and that is the v3.6 parted in /usr/bin as confirmed by the command which parted -a.
My question:
At the end when I do $ parted -v why does it not see parted v3.6 but instead it says: “bash: /usr/local/sbin/parted: No such file or directory”?
If I open a new shell, a new tab in Konsole, then parted -vdoes see the correct v3.6
Because your $PATH is a variable, and that variable is only read when you open a login shell, although what you say leads me to suspect that — at least on your system — it is also being read when starting an interactive shell. Maybe you have your $PATH defined in ~/.bashrc — normally it would in be ~/.bash_profile only.
Either way, the location of some of the commands in the $PATH is hashed, meaning that their location is read into a cache in memory, so that the shell doesn’t need to effectively scan each of the directories of the $PATH. Presumably that is what’s happening here, i.e. you changed the name of the executable, but it doesn’t correspond anymore to what’s in the cache.
If you create an alias in a shell it’ll work in that shell, when you open a new shell it doesn’t exist, unless you put it in your config (~/.bashrc or similar) first.
@Aragorn " Either way, the location of some of the commands in the $PATH is hashed, meaning that their location is read into a cache in memory…"
Thanks for confirming what I suspected myself, yesterday, five posts ago.
@dmt
No, I did not create an alias. And if I had, by your logic, then parted -v would not work correctly when I opened a new shell window. But as I have described above in about five different posts, after I rename a binary, opening a new shell window is the only way parted -v will work correctly for me.
It seems reloading the shell is required after a simple binary file rename which I consider an inconvenient limitation of how the shell is designed to work.
It would work if the first terminal had an alias defined and the second didn’t. You hadn’t told us anything that would preclude that, and people had mentioned aliases earlier.
Inconvenient indeed, but you can . ~/.bashrc (. is the same as source) instead of opening a new terminal/shell.
I forgot to switch to bash when testing earlier, and zsh doesn’t exhibit this issue. I should probably pay more attention to the prompt.
I can’t remember running into this before, but it’s been ages since I used bash as my shell.
@dmt This thread has gone on so long I guess it’s become impossible to keep everything in mind. In my post above from 29 June after summarising every ones helpful advice I tagged on an extra “Add Finally” section which I should really have put in a separate thread. In there I wasn’t concerned about using an alias I was just asking for clarification about why renaming my patched parted binary from “parted-patched” to “parted” and back again was giving incorrect results when I then ran the parted -v within the same shell. No one seemed to notice that question!
I tried your suggestion and of course you are right, using an alias in .bashrc would ensure parted -v always gives a sensible result even within the same shell but that’s not really a convenient solution to let me rename a binary that’s in my PATH using the mv command from the shell to whatever I want and for it to be properly recognised within the same shell after I rename it.
Useful to know . ~/.bashrc reloads the shell with instructions from there but I might anyway switch to zsh since as you say it doesn’t have this issue.
It seems I was a bit hasty on that, I thought I’d checked properly, but apparently not for zsh, so I was only partly right. Also I have a custom .zshrc, and there may be an option specified which creates this behaviour.
zsh properly detects when a file is missing and checks anew, but it does cache it and uses the file should it exist. I think the bash equivalent is shopt -s checkhash. My usage wouldn’t normally bring this caching to light.
However we can clear the hashing/caching before the prompt is shown, which will force a path search.
bash
# Add this to ~/.bashrc
PROMPT_COMMAND='hash -r'
# I'm using this to test
# both copies are the same
$ cat /usr/local/testy
#!/usr/bin/bash
echo $0
$ which testy
/usr/local/bin/testy
$ testy
/usr/local/bin/testy
$ sudo mv /usr/local/bin/testy{,.bak}
$ which testy
/usr/bin/testy
$ testy
/usr/bin/testy
$ sudo mv /usr/local/bin/testy{.bak,}
$ which testy
/usr/local/bin/testy
$ testy
/usr/local/bin/testy
zsh
# Add this to ~/.zshrc
precmd() { hash -r; }
# Again I'm using this to test
# both copies are the same
$ cat /usr/local/testy
#!/usr/bin/bash
echo $0
% which testy
/usr/local/bin/testy
% testy
/usr/local/bin/testy
% sudo mv /usr/local/bin/testy{,.bak}
% which testy
/usr/bin/testy
% testy
/usr/bin/testy
% sudo mv /usr/local/bin/testy{.bak,}
% which testy
/usr/local/bin/testy
% testy
/usr/local/bin/testy