1

I do not understand how PATH & $PATH is treated by the shell. Consider the following: alias testCMD=PATH=$PATH

I can run

$ testCMD vim

But it would not work if I declared alias testCMD=$PATH

Also I could not run:

$ PATH vim 

or

$ $PATH vim 

It's just a bit counterintuitive to how other aliases work. I hope you understand my confusion.

2
  • You seem to be mixing up aliases and variables. In the shell language they're different and their expansion follows different rules and happens at different times. This is neither "logical" nor intutive -- I suggest you go read some good documentation like the bash manual instead of trying to whack-a-mole their quirks one by one.
    – user313992
    Commented Feb 10, 2021 at 22:16
  • I like to put catsup on my food, but when I put cats on my food, they run away. I like to eat pizza and pie, but I can’t eat pi (π) because it’s a number. You are trying to run PATH vim and $PATH vim; this looks like you are taking fragments of valid commands and expecting them to be meaningful. Commented Feb 12, 2021 at 19:43

1 Answer 1

3

Your shell stores a variety of key-value pairs called environment variables. Your PATH is just one example of one of these environment variables.

Without a PATH variable set, you would need to manually set the full path of every program you execute. Eg, you couldn't just run date, you would need to run /usr/bin/date every time. And if you later install a custom version of Date in /usr/local/bin/, you would need to run it as /usr/local/bin/date.

While inconvenient, this isn't impossible, so you see PATH is actually optional. What the PATH is for, therefore, is to simply automatically detecting locations for programs.

Since programs can reside in multiple places across the system, the PATH isn't just one directory. Instead, it is a colon-separated list of directories. When you execute a command in your shell, the shell searches these directories in order to try and find the command you want to run.

Going back to the date example, you could set PATH=/usr/local/bin:/usr/bin if you prefer to prioritise custom programs under /usr/local/bin, with fallback to /usr/bin if it's not in /usr/local/bin. Then when you run date, the shell will see /usr/local/bin/ at the front of the PATH list, so it will find /usr/local/bin/date. If you deleted /usr/local/bin/date, the shell will still find /usr/bin/date, since /usr/bin/ is second in the PATH.

When you run alias testCMD=PATH=$PATH, you get an alias which probably looks a bit like this:

testCMD='PATH=.:/usr/local/bin:/usr/bin:/bin'

Therefore when you run testCMD vim, what the shell see is,

PATH=.:/usr/local/bin:/usr/bin:/bin vim

This just gives a one-off directive telling the shell where to look for vim. If you just ran vim by itself, you would get the same result, because your testCMD alias isn't changing the value of PATH.

Here is the difference if you do change the PATH:

$ PATH=/foo vim
bash: vim: command not found

Because the shell tried to look in some directory called /foo and there was definitely no vim in there.

Going on to the examples you gave where it wasn't working, it's because you're not doing a variable assignment. There is a difference between PATH=/foo vim and PATH vim. In PATH vim, the shell thinks you're trying to find a program called PATH. The shell will then look in every directory in $PATH looking for a program called PATH. Since you (probably) don't have a PATH command in any of those directories, you would get,

$ PATH vim
bash: PATH: command not found

The same principle holds when prefixing vim with just the value of $PATH: there is no assignment, so the shell thinks $PATH is intended to be the name of some program. This is why you get:

$ $PATH vim
bash: .:/usr/local/bin:/usr/bin:/bin: No such file or directory

Overall, you usually just need to set PATH once in your ~/.bashrc or ~/.bash_profile. The exception would be if you're switching around between a variety of toolchains. This is actually what Python virtualenvs are for, to automate reconfiguring the PATH. Environment module systems such LMod are another powerful way of manipulating the PATH when required.

8
  • 1
    That was a fast -1. Want to explain why?
    – cryptarch
    Commented Feb 10, 2021 at 20:45
  • 2
    +1 for the lack of comment on the downvote and thoughtful answer. Commented Feb 10, 2021 at 20:48
  • 2
    Thanks for the thorough answer. I guess it comes down how bash/shell interprets the command. I did not expect that the shell interprets $PATH as a program. And very interesting that $ PATH=.:/usr/local/bin:/usr/bin:/bin vim works, but $ $PATH does not
    – Marcellvs
    Commented Feb 10, 2021 at 21:05
  • I didn’t downvote, but (1) I get heartburn from depictions of PATH beginning with .. (2) You say “Your shell stores a variety of key-value pairs called environment variables, but ignore the fact that aliases are also key-value pairs, which seems to be a key component of the OP’s confusion.  … (Cont’d) Commented Feb 12, 2021 at 19:43
  • (Cont’d) …  (3) You say that it’s possible (although somewhat unusual) for a user to change PATH manually, and you talk about the OP’s testCMD alias, but you imply that it’s a no-op, saying that “your testCMD alias isn't changing the value of PATH.”  But, in fact, the OP’s testCMD alias is resetting PATH to its value at the time the alias was defined, and you sidestep that. Commented Feb 12, 2021 at 19:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .