30

What is $PATH?

How can I have commands/programs which are only available for me?
I have seen this path ~/bin mentioned before, but what is it used for, and how do I use it?

2
  • I am somewhat experimenting because this is more FAQ or wiki material than a "real question". It was prompted because I mentioned ~/bin on a previous answer (in the linked sidebar to the right) and someone commented on how to add it to PATH: now instead of brief comments, we can link to this post when ~/bin is mentioned.
    – Roger Pate
    Oct 28, 2010 at 0:48
  • Also see Where should I put my bash scripts?
    – user68186
    Mar 17, 2023 at 17:22

2 Answers 2

28

$PATH is an environment variable used to lookup commands. The ~ is your home directory, so ~/bin will be /home/user/bin; it is a normal directory.

When you run "ls" in a shell, for example, you actually run the /bin/ls program; the exact location may differ depending on your system configuration. This happens because /bin is in your $PATH.

To see the path and find where any particular command is located:

$ echo $PATH
/home/user/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:...
$ which ls     # searches $PATH for an executable named "ls"
/bin/ls
$ ls           # runs /bin/ls
bin  desktop  documents  downloads  examples.desktop  music  pictures  ...
$ /bin/ls      # can also run directly
bin  desktop  documents  downloads  examples.desktop  music  pictures  ...

To have your own private bin directory, you only need to add it to the path. Do this by editing ~/.profile (a hidden file) to include the below lines. If the lines are commented, you only have to uncomment them; if they are already there, you're all set!

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ]; then
  PATH="$HOME/bin:$PATH"
fi

Now you need to create your ~/bin directory and, because .profile is run on login and only adds ~/bin if it exists at that time, you need to login again to see the updated PATH.

Let's test it out:

$ ln -s $(which ls) ~/bin/my-ls   # symlink
$ which my-ls
/home/user/bin/my-ls
$ my-ls -l ~/bin/my-ls
lrwxrwxrwx 1 user user 7 2010-10-27 18:56 my-ls -> /bin/ls
$ my-ls          # lookup through $PATH
bin  desktop  documents  downloads  examples.desktop  music  pictures  ...
$ ~/bin/my-ls    # doesn't use $PATH to lookup
bin  desktop  documents  downloads  examples.desktop  music  pictures  ...
3
  • 3
    One thing to watch out for when using which is that it will only find commands that are binaries in the filesystem, it does not report shell builtin, aliases, or functions. Often, it's more useful to use type to see how an actual command will be resolved by the shell; e.g.: which echo and type echo will report different things, which returns '/bin/echo' but 'type' returns that it's a shell builtin, which the shell will prefer over the file in '/bin'. Nov 2, 2010 at 16:23
  • @Steve Beattie, +1. which is better replaced by type or command in interactive shells, and it's completely useless in scripts.
    – geirha
    Feb 3, 2011 at 22:56
  • One thing to note that I just noticed — $HOME variable in $PATH for some reason doesn't work, i.e. one have to use ~ sign instead.
    – Hi-Angel
    Dec 6, 2015 at 5:42
19

Regarding ~/bin or ~/.local/bin and commands/programs only available to your user

Recent Ubuntu versions include the ~/bin and ~/.local/bin directories in your $PATH, but only if either exist.

If none of these directory exists:

  1. Ensure that your ~/.profile contains the following stanza (the default ~/.profile already does):

    # set PATH so it includes user's private bin if it exists
    if [ -d "$HOME/bin" ] ; then
        PATH="$HOME/bin:$PATH"
    fi
    
    # set PATH so it includes user's private bin if it exists
    if [ -d "$HOME/.local/bin" ] ; then
        PATH="$HOME/.local/bin:$PATH"
    fi
    
  2. Create the ~/bin and/or ~/.local/bin directory:

    mkdir -p ~/bin
    

    and/or

    mkdir -p ~/.local/bin
    
  3. Either reboot your computer, or force bash to re-read ~/.profile:

    exec -l bash
    
2
  • Thanks for the "reboot or exec -l bash" tip. What does the -l flag do? I'm not finding an explanation in man exec. Oct 19, 2013 at 6:11
  • 3
    exec -l will execute bash as a login shell [wiki.bash-hackers.org/commands/builtin/exec]. In short, it force bash to re-read /etc/profile and ~/.profile. Just running exec bash will only re-read ~/.bashrc. Oct 19, 2013 at 17:14

You must log in to answer this question.