This is my first post in this blog, and I thought I should make something useful out of it, and teach you guys how to add directories to your PATH variable in a Linux/Unix system. So without further ado, let's get to it.
For this small tutorial, I'm assuming you're already acquainted with the terminal and you know the most basic commands, such as ls, cd, etc. And you've already written your own shell scripts, though that could also be talked about in another post.
ls
cd
Have you ever wondered why some commands require you to cd into the same directory of the executable, and type ./command, while others just need the name of the command, and can be executed from anywhere? That's because those commands are executable files in one of the directories in your PATH. "And what is this PATH?" you might ask. It is a list of directories with all the directories that contain the commands you can execute from your terminal. To be more precise, it is an environment variable with a single string that shows you the full path to each of the directories your system will search for the commands you execute, separated by colons. To see the value of your PATH, you can use the command echo ${PATH}. Your tipical PATH will look something like the one below.
./command
PATH
echo ${PATH}
$ echo "${PATH}" /usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin
These are the most basic directories to guarantee your system works as it should. With the exception of /usr/local/bin, if you erase any of them from your PATH, then you're in for a bad surprise. Though, there are also ways to circumvent that. We'll get to that in a moment.
So now, you can see the directories available in your PATH. But how can you add more to the list? Let's say you want to add ~/.local/bin to the list, which is in fact a pretty common directory for your own scripts. To add it, you can do it in two simple steps:
~/.local/bin
$ PATH="${HOME}/.local/bin:${PATH}" $ export PATH
The first command creates a shell variable with the same name as the environment variable we want to replace, and it references the variables HOME and PATH in its value. The second command exports it so it can be read by all child processes, effectively making it an environment variable.
HOME
Notice the symbols, such as braces, quotation marks, equal sign and dollar sign. The dollar sign makes a reference to a shell variable or an environment variable, allowing you to read its value. The braces are optional, but they ensure you take the whole word as the name of the variable. You can use $HOME to read the value of HOME, for example. But if you have variables called H, HO or HOM, they'll get in the way. So the braces prevent that. The quotation marks are also optional, but they ensure the value read is a single string. Not really needed in this case, but it's nice to get used to them when setting variables. And notice the name of the variable and the value after the assignement are "glued" to the equal sign. It is actually supposed to be like that, and putting spaces either before or after it will mess it up. Oh, and using ~ will not work as your home directory. You have to use the HOME environment variable, which expands into the full path of your home directory.
$HOME
H
HO
HOM
~
However, this new PATH is only valid for the current instance of the terminal. If you close it and open another one, the variable will be reset to its previous value. That happens because environment variables can only pass from parent to child processes, not the other way around. So how can you make it valid for all terminals you might open up? You can do it in your .profile, in most cases. If your login shell is bash, and you have a .bash_profile or .bash_login, those will take priority over .profile. If you use zsh, then you have .zprofile. If you use startx to log in, then you have to edit .xinitrc. And if you use xdm as your display manager, then you have to edit .Xresources.
.profile
.bash_profile
.bash_login
.zprofile
startx
.xinitrc
xdm
.Xresources
So now, what happens if you erase the PATH variable? Or you forget the dollar sign in ${PATH}, which is basically the same thing? Next time you try to log in, if you type your password wrong, you will get an error message and not be able to log in, obviously. But if you type it right, it will simply error silently, and you'll also not be able to log in. So what you should do is press Ctrl + Alt + F2 to go into tty2, or any other up until tty6. The tty1 is where your graphical session is, for most display managers. Once you reach the tty, type in your username and password. You should be able to log in, and be greeted with an entirely black terminal covering your whole screen. No GUI here. Also, no commands. You have to write the whole path for each command, but if you log into root with sudo, the PATH should be fine. So, putting the commands you need:
${PATH}
Ctrl + Alt + F2
$ /bin/sudo -i # cd /home/wizard # use your own username # vim .profile
The first command requires the full path, since you borked the PATH environment variable. The -i flag means --login, which will let you use the root user account, with all its privileges. Then you change directory into your own user's HOME. If you use cd, cd ~ or cd $HOME, you will be taken to /root, the root user's home directory. You DO NOT want to mess with this directory, so make sure you change into the right one. You can check your current directory with pwd. Now, open the .profile file with your favorite text editor. GUI editors won't work here, so you can't use gedit, kate or vscode. If you don't know how to use vim or nano, then you can rename .profile with either one of those commands below:
-i
--login
root
cd ~
cd $HOME
/root
pwd
# mv .profile old_profile # mv can be used to either move or rename
After that, you can type exit twice to log out, and go back to tty1 with Ctrl + Alt + F1. If you used vim or nano, or nvim, or emacsclient --tty (who knows), then your PATH variable is edited correctly. If you renamed it, then you can rename it back to .profile (or whatever your usual login script name is) and make sure you write it correctly this time.
exit
Ctrl + Alt + F1
vim
nano
nvim
emacsclient --tty
There you go. Your new directory is added to your PATH. Put whatever scripts or binaries into this new directory, and hack away!