Linux path how to specify folder paths. PATH environment variable. Adding User and System Environment Variables in Linux

When you enter the command in command line, you are basically telling the shell to run an executable with a given name. On Linux these executable programs, like ls, find, file and others tend to live in several different directories on your system. Any file with executable permissions stored in these directories can be run from anywhere. The most common directories that contain executable programs are /bin, /sbin, /usr/sbin, /usr/local/bin, and /usr/local/sbin.

But how does the shell know which directories to look for executable programs or does the shell search throughout file system?

The answer is simple. When you issue a command, the shell searches all directories specified in the user's $PATH variable for an executable file with that name.

This article shows you how to add directories to your system $PATH variable.

What is $PATH in Linux

The $PATH environment variable is a colon-colonized list of directories that tells the shell which directories to search for executable files.

To check which directories you have in your $PATH variable, you can use the printenv or echo command:

Echo $PATH

The output will look something like this:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

If you have two executable files with the same name located in two different directories, the shell will run the file that is in the directory that comes first in $PATH.

Adding a directory to your $PATH

There are situations where you may want to add other directories to your $PATH variable. For example, some programs may be installed in different locations, or you may want to have a dedicated directory for your personal entries but be able to run them without specifying the absolute path to the executables. To do this, you just need to add the directory to your $PATH.

Let's say you have a directory called bin located in your home directory in which you store your shell scripts. To add a directory to your $PATH variable:

The export command exports the modified variable to the child environments of the shell processes.

Now you can run your scripts by simply typing the name of the executable script without specifying the full path to the executable file.

However, this change is temporary and only affects the current shell session.

To make the change permanent, you need to define a $PATH variable in your shell configuration files. On most Linux distributions, when starting a new session, environment variables are read from the following files:

  • Global shell configuration files such as /etc/environment and /etc/profile. Use this file if you want the new directory to be added to everyone system users$PATH.
  • Configuration files for individual user shells. For example, if you are using Bash, you can set the $PATH variable in the ~/.bashrc file, and if you are using Zsh, the file name is ~/.zshrc.

In this example, we will set a variable in the ~/.bashrc file. Open the file in text editor and add the following line at the end:

Nano ~/.bashrc

Export PATH="$HOME/bin:$PATH"

Save the file and load the new $PATH value into the current shell session using :

Source ~/.bashrc

To confirm that the directory was added successfully, print its $PATH value by typing:

Echo $PATH

Conclusion

Adding new directories to your user or global $PATH is quite simple. This allows you to run commands and scripts stored in non-standard locations without having to enter the full path to the executable.

The same instructions apply for any Linux distribution, including , CentOS, RHEL, Debian and Linux Mint.

Feel free to leave a comment if you have any questions.

What it is? Many of the commands you enter at the command prompt require the use of an external program that is loaded from the file system. For example, commands like mkdir and wc are actually located in the /bin folder.

When you enter an instruction that the Bash shell does not recognize, it tries to execute it as a program and returns an error if it does not find a program with that name. And this applies not only to the basic commands that we looked at, because from the command line you can run any program.


But how if there is a file Linux system knows which programs to run from which directories? The OS uses a system environment variable to specify a subset of folders to search when receiving an unknown command. This variable is called PATH and can be displayed with the following echo command (the $ symbol is required):

Echo $PATH

The output of this command will look like the following seven absolute folder paths, separated by colons:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Each time you enter an unknown Linux commands will look through each of the folders specified in the environment variable in the order they were specified, trying to find a program with the same name. If the program is found, it runs; otherwise an error message is displayed. But it won’t be a mistake if you buy your beloved silver rings as a gift. Silver will decorate any woman!

These seven folders provide easy access to all major programs in operating system, including . Any programs outside of these seven folders cannot be launched by simply typing their name into the command line.

For example, you downloaded the diary utility from the Internet to your home folder. If you enter its name at the command prompt, you will receive an error message because it is in a folder that is not included in the system path. To run this program, enter the following line (remember, the ~ symbol is shorthand for your home folder):

If you saved it in a folder outside of your specified path, you will have to enter the absolute path and file name to run the utility.

Of course, it is assumed that diary is a simple standalone program that does not require installation, because most major applications will place the program's executable file somewhere in your specified path during the installation process. Like this PATH environment variable, enjoy it for your health!

export PATH=~/opt/bin:$PATH

Export PATH=$PATH:~/opt/bin

9 Solutions collect form web for “How to correctly add a path to PATH?”

Simple things

PATH=$PATH:~/opt/bin PATH=~/opt/bin:$PATH

depending on whether you want to add ~/opt/bin at the end (to search all other directories if there is a program with the same name in multiple directories) or at the beginning (to search before all other directories).

You can add multiple entries at the same time. PATH=$PATH:~/opt/bin:~/opt/node/bin or changes to the ordering are just fine.

You don't need to export if the variable is already in the environment: any change to the variable's value is reflected in the environment. The PATH is almost always in the environment; All unix systems install it very early (usually in the very first process, in fact).

If your PATH is built in different components, you may end up with duplicate entries. See How to add the path to the source directory to be detected by Unix, what is the command? and remove duplicate $PATH entries using awk command to avoid adding duplicates or removing them.

Where to put

Note that ~/.bash_rc is not readable by any program, and ~/.bashrc is the configuration file for interactive bash instances. You should not define environment variables in ~/.bashrc . The correct place to define environment variables such as PATH is ~/.profile (or ~/.bash_profile if you don't need non-bash shells). See what is the difference between them and which one should I use?

Notes on non-bash shells

In bash, ksh and zsh, export is a special syntax, and both PATH=~/opt/bin:$PATH and export PATH=~/opt/bin:$PATH do everything right. On other Bourne/POSIX shells such as dash (which is /bin/sh on many systems), export is parsed like a normal command, which implies two differences:

  • ~ is only parsed at the beginning of a word, except in assignments (see section "How to add a path to a source directory that will be detected by Unix, what command?").
  • $PATH outside double quotes breaks if PATH contains spaces or \[*? ,

So in dash-like shells, export PATH=~/opt/bin:$PATH sets PATH to the literal string ~/opt/bin/: followed by the value of PATH up to the first place. PATH=~/opt/bin:$PATH (fuzzy assignment) doesn't require quotes and does the right thing. If you want to use export in a portable script, you need to write export PATH="$HOME/opt/bin:$PATH" .

¹ This was not true in Bourne rockets (as in the real Bourne shell, not modern POSIX-style shells), but you're unlikely to encounter shells that old these days.

It works anyway, but they don't do the same thing: PATH elements are checked from left to right. In the first example executable files in ~/opt/bin will take precedence over those installed in e.g. /usr/bin , which may or may not be what you want.

Particularly from a security perspective, it is dangerous to add paths to the front, because if someone can gain write access to your ~/opt/bin , they could, for example, place other ls that you "d then probably use instead of /bin/ls without noticing Now imagine the same as for ssh or your browser or choice... (The same thing can be done three times in your path.)

I'm confused by question 2 (since it was removed from the question because it was related to an unrelated issue):

What effective method adding additional paths to different lines? Initially I thought this might do the trick:

Export PATH=$PATH:~/opt/bin export PATH=$PATH:~/opt/node/bin

but it doesn't because the second assignment not only adds ~/opt/node/bin but also all previously assigned PATH .

This is a possible solution:

Export PATH=$PATH:~/opt/bin:~/opt/node/bin

but for readability I'd rather have one destination per path.

If you say

PATH=~/opt/bin

This All, what will be in your PATH. PATH is just an environment variable, and if you want to add to PATH, you need to rebuild the variable with exactly the content you want. So what you give as an example in question 2 is exactly what you want to do, unless I'm completely missing the point of the question.

I use both forms in my code. I have a general profile that I install on every computer I work on that looks like this to accommodate potentially missing directories:

Export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11 # add optional items to the path for bindir in $HOME/local/bin $HOME/bin; do if [ -d $bindir ]; then PATH=$PATH:$(bindir) fi done

Linux determines the executable search path from the $PATH environment. To add the /data/myscripts directory to the top of the $PATH environment, use the following:

PATH=/data/myscripts:$PATH

To add this directory to the end of the path, use the following command:

PATH=$PATH:/data/myscripts

But the previous ones are not enough because when you set an environment variable inside a script, that change only takes effect inside the script. This limitation is limited in only two ways:

  • If you export an environment variable in a script, it is effective across any programs called by the script. Note that this is not effective in a program called a script.
  • If the program calling the script does so by including instead of calling, any environment changes to the script are effective on the calling program. This inclusion can be done using the dot command or the source command.

$HOME/myscript.sh source $HOME/myscript.sh

Inclusion basically includes the "callable" script in the "call" script. This is similar to #include in C. So it is effective inside a script or calling program. But of course this is not effective for any programs or scripts called by the calling program. To make it effective down to the call chain, you must follow the environment variable setting using the export command.

As an example, the bash shell program includes the contents of the .bash_profile file by inclusion. So, adding the following 2 lines to .bash_profile:

PATH=$PATH:/data/myscripts export PATH

effectively puts those 2 lines of code into a bash program. Thus, in bash variable$PATH includes $HOME/myscript.sh , and because of the export statement, any programs called by bash will have $PATH modified. And since any programs launched from the bash prompt are called by bash, the new path is valid for anything you launch from the bash prompt.

The bottom line is that to add a new directory to the path, you need to append or append the directory to the $PATH environment variable in a script included in the shell, and you must export the $PATH environment variable.

Additional Information Here

For some time I have kept with me two functions pathadd and pathrm that help add elements to a path without having to worry about duplications.

pathadd takes one path argument and an optional after argument which if added will be added to PATH otherwise it will add it.

In almost every situation, if you add a path, you probably want to override everything that's already in the path, so I prefer adding by default.

Pathadd() ( newelement=$(1%/) if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then if [ " $2" = "after" ] ; then PATH="$PATH:$newelement" else PATH="$newelement:$PATH" fi fi ) pathrm() ( PATH="$(echo $PATH | sed -e "s; \(^\|:\)$(1%/)\(:\|\$\);\1\2;g" -e "s;^:\|:$;;g" -e "s ;::;:;g")" )

Place them in any script you want to change the PATH environment and you can now do so.

Pathadd "/foo/bar" pathadd "/baz/bat" after export PATH

You are guaranteed not to add to a path if it already exists. If you now want /baz/bat to be at start.

Pathrm "/baz/bat" pathadd "/baz/bat" export PATH

Any path can now be brought to the front if it is already on a path without doubling.

I can't speak for other distributions, but Ubuntu has a file, /etc/environment, which is the standard search path for all users. Since my computer is only used by me, I put whatever directories I want in my path, as long as it's a temporary addition that I put into the script.

Here's my solution:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: "!x[$0]++" | sed "s/\(.*\).\(1\)/\1 /")

Nice light liner that doesn't leave trailing:

For me (on Mac OS X 10.9.5) adding the path name (eg /mypathname) to the /etc/paths file worked very well.

Before editing, echo $PATH is returned:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

After editing /etc/paths and restarting the shell, the $PATH variable is added with /pathname . Indeed, echo $PATH returns:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

What happened was that /mypathname was added to $PATH .

To add a new path to the PATH environment PATH:

Export PATH=$PATH:/new-path/

To make this change apply to every shell you open, add it to a file that the shell will call when you call it. In different shells this could be:

  • Bash Shell: ~/.bash_profile, ~/.bashrc or profile
  • Korn Shell: ~/.kshrc or .profile
  • Z Shell: ~/.zshrc or .zprofile

For example

# export PATH=$PATH:/root/learning/bin/ # source ~/.bashrc # echo $PATH

You can see the provided path in the above output.

All files in Linux have a specific address in the file system with which we can access them using a file manager or console utilities. This is a fairly simple topic, but many beginners have difficulty with it.

In today's short article we will look at what the path to a Linux file is, what it can be, how to write it correctly and much more. If you had difficulties with this before, then after reading the article everything will become completely clear.

File paths in Linux

The Linux file system is very different from Windows. We will not consider its structure; that was done earlier. We will focus on working with files.

The most important difference is that the file address does not start from the drive, for example, C:\ or D:\ as it happens in Windows, but from the root, the root system directory to which all others are connected. His address - /. And here we need to talk about addresses. Linux file paths use forward slash "/" to separate directories in the address, and this is different from what you are used to seeing on Windows - \.

For example, if in Windows full the path to the file on the desktop looked like C:\Users\Sergiy\Desktop\, then the file path in Linux would be simply /home/sergiy/desktop/. With this, everything is simple and clear so far. But problems arise further.

In the Linux operating system, there can be several types of file paths. Let's look at what paths there are in Linux:

  • Full, absolute linux path from the filesystem root- you have already seen this path in the example above, it starts from the root “/” and describes the entire path to the file;
  • Linux relative path- this is the path to the file relative to the current folder; such paths often cause confusion.
  • Path relative to the current user's home folder.- path in the file system, but not from the root, but from the current user’s folder.

Let’s now take a closer look at what these paths look like in Linux, and also look at a few examples to make it completely clear. For the demonstration, we will use the ls utility, which is designed to view the contents of directories.

For example, we have a directory like this in our home folder with four files in it:

This is what the full Linux path to one of the files will look like:

ls /home/sergiy/tmp/file1

This is already a relative Linux path, which starts from the home folder, it is designated ~/. Note, not ~, namely ~/. Then you can specify subfolders, in our case tmp:

Well, or the file path in Linux, relative to the current folder:

The first link points to the current folder (.), the second (..) points to a higher folder. This opens up even greater possibilities for catalog navigation. For example, to refer to a file in the current folder you can use the following construct:

This is of no use when viewing the contents of a file. But it is very important when executing the program. Because the program will first be searched in the PATH environment, and only then in this folder. Therefore, if you need to run a program that is located in the current folder and it is called exactly the same as the one in the /bin directory, then without an explicit link that you need to look for the file in the current folder, nothing will work.

Such constructs can occur quite often when compiling programs. You can use all these symbols and linux file paths not only in the terminal, but also in any file manager, which can be very convenient.

But Linux terminal provides even greater opportunities. You can use simple wildcard characters directly in file or directory addresses. For example, you can list all files starting with f:

Or you can even search not only in the tmp folder, but in any subfolder of your home folder:

And all this will work, perhaps it is not always necessary and practical. But in certain situations it can help a lot. These functions are implemented at the Bash shell level, so you can use them in any command. The shell looks at how many files were found and calls a command for each of them.

conclusions

That's all. Now you know everything you need to not only correctly write the path to linux file, but also perform more complex actions, such as searching for files or navigating through directories using the cd command. If you have any questions, ask in the comments!

Related posts:


I'm wondering where the new path should be added to the PATH environment variable. I know this can be accomplished by editing .bashrc (for example), but it's not clear how to do this.

Thus:

Export PATH=~/opt/bin:$PATH

Export PATH=$PATH:~/opt/bin

11 answers

Simple material

PATH=$PATH:~/opt/bin PATH=~/opt/bin:$PATH

depending on whether you want to add the ~/opt/bin code to the end (to search all other directories if there is a program with the same name in multiple directories) or to the beginning (to search before all other directories).

You can add multiple entries at the same time. PATH=$PATH:~/opt/bin:~/opt/node/bin or changes to the ordering are just fine.

You don't need to export if the variable is already in the environment: any change to the variable's value is reflected in the environment.¹ PATH is pretty much always in the environment; all unix systems install it very early (usually in the very first process, in fact).

If your PATH is created by many different components, you may end up with duplicate entries. See How to add a path to your home directory that will be detected by Unix, which command? and Remove duplicate $PATH entries using the awk command to avoid duplicates or remove them.

Where to put

Note that ~/.bash_rc is not readable by any program, and ~/.bashrc is the configuration file for interactive bash instances. You should not define environment variables in ~/.bashrc . The correct place to define environment variables such as PATH is ~/.profile (or ~/.bash_profile if you don't like shells other than bash). See What is the difference between them and which one should I use?

Notes on non-bash shells

In bash, ksh and zsh, export is a special syntax, and both PATH=~/opt/bin:$PATH and export PATH=~/opt/bin:$PATH do the right thing even. On other Bourne/POSIX shells, such as dash (which is /bin/sh on many systems), export is parsed like a normal command, which implies two differences:

  • ~ is only parsed at the beginning of a word, except in assignments (see How do I add a home directory path that will be detected by Unix that requires the command? ;
  • $PATH external double quotes breaks if PATH contains spaces or \[*? .

So, in shells like dash, export PATH=~/opt/bin:$PATH sets PATH to the literal string ~/opt/bin/: followed by the PATH value up to the first place. PATH=~/opt/bin:$PATH (simple assignment) doesn't require quotes and does everything right. If you want to use export in a portable script, you need to write export PATH="$HOME/opt/bin:$PATH" or PATH=~/opt/bin:$PATH export PATH (or PATH=$HOME/opt/bin: $PATH export PATH for portability even to the Bourne shell, which does not accept export var=value and did not do tilde expansion).

¹ This was not true in the Bourne shells (as in the actual Bourne shell, not modern POSIX-style shells), but you're unlikely to encounter shells that old these days. Sub>

Either way works, but they don't do the same thing: PATH elements are checked from left to right. In the first example, executables in ~/opt/bin will take precedence over those installed in, for example, /usr/bin , which may or may not be what you want.

In particular, it's dangerous from a security perspective to add paths to the front, because if someone can get write access to your ~/opt/bin , they might put another ls for example, which you'll probably use instead /bin/ls without noticing. Now imagine the same for ssh or your browser or choice... (Same thing three times put on your path.)

I'm confused about question 2 (since it was removed from the question because it was related to not related problem):

What is an efficient way to add additional paths to different lines? Initially I thought this might do the trick:

Export PATH=$PATH:~/opt/bin export PATH=$PATH:~/opt/node/bin

But that's not because the second assignment not only adds ~/opt/node/bin but also the previously assigned PATH .

This is a possible workaround:

Export PATH=$PATH:~/opt/bin:~/opt/node/bin

But for readability I'd rather have one destination per path.

If you say

PATH=~/opt/bin

This all, which will be in your PATH. PATH is just an environment variable, and if you want to add to PATH, you need to rebuild the variable with exactly the content you want. That is, what you give as an example in question 2 is exactly what you want to do, unless I completely missed the point of the question.

I use both forms in my code. I have a general profile that I install on every machine I work on that looks like this, to host potentially missing directories:

Export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11 # add optional items to the path for bindir in $HOME/local/bin $HOME/bin; do if [ -d $bindir ]; then PATH=$PATH:$(bindir) fi done

Linux defines the executable search path with the $PATH environment variable. To add the /data/myscripts directory to the beginning of the $PATH environment variable, use the following:

PATH=/data/myscripts:$PATH

To add this directory to the end of the path, use the following command:

PATH=$PATH:/data/myscripts

But the previous ones are not enough because when you set an environment variable inside a script, that change only takes effect inside the script. This limitation is limited in two ways:

  • If you export an environment variable within a script, it is effective within any programs called by the script. Note that this is not effective in the program that called the script.
  • If the program calling the script does so by including instead of calling, any environment changes to the script are effective on the calling program. This inclusion can be done using the dot command or the source command.

$HOME/myscript.sh source $HOME/myscript.sh

Inclusion basically includes the "callable" script in the "call" script. This is similar to #include in C. So it is effective inside a script or calling program. But of course this is not effective for any programs or scripts called by the calling program. To make it effective down to the call chain, you must follow the environment variable setting using the export command.

As an example, the bash shell program includes the contents of the .bash_profile file by inclusion. So put the following 2 lines in .bash_profile:

PATH=$PATH:/data/myscripts export PATH

effectively puts those 2 lines of code into a bash program. So in bash, the $PATH variable includes $HOME/myscript.sh, and because of the export statement, any programs called by bash have the $PATH variable modified. And since any programs you launch from the bash prompt are called by bash, the new path applies to anything you launch from the bash prompt.

The bottom line is that to add a new directory to the path, you need to append or append the directory to the $PATH environment variable in a script included in the shell, and you must export the $PATH environment variable.

I've kept with me for some time two functions pathadd and pathrm that help add elements to a path without worrying about duplications.

pathadd takes one path argument and an optional after argument, which if added will be added to PATH , otherwise it will add it.

In any situation, if you're adding a path, you probably want to override anything that's already in the path, so I prefer adding by default.

Pathadd() ( newelement=$(1%/) if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then if [ " $2" = "after" ] ; then PATH="$PATH:$newelement" else PATH="$newelement:$PATH" fi fi ) pathrm() ( PATH="$(echo $PATH | sed -e "s; \(^\|:\)$(1%/)\(:\|\$\);\1\2;g" -e "s;^:\|:$;;g" -e "s ;::;:;g")" )

Place them in whatever script you want to change the PATH environment and you are now done.

Pathadd "/foo/bar" pathadd "/baz/bat" after export PATH

You are guaranteed not to add a path if it already exists. If you want /baz/bat to be run first.

Pathrm "/baz/bat" pathadd "/baz/bat" export PATH

Any path can now be moved to the front if it is already on a path without doubling.

Bulletproof addition/pre-preparation method

There are many considerations involved in choosing to add and add. Many of them are covered in other answers, so I won't repeat them here.

The important point is that even if system scripts don't use this (I wonder why) *1, it's a bulletproof way to add a path (e.g. $HOME/bin) to the PATH environment variable

PATH="$(PATH:+$(PATH):)$HOME/bin"

to add (instead of PATH="$PATH:$HOME/bin") and

PATH="$HOME/bin$(PATH:+:$(PATH))"

to add (instead of PATH="$HOME/bin:$PATH")

This avoids a false leading/trailing colon when $PATH is initially empty, which can have unwanted side effects and can be a nightmare to find (this answer briefly addresses the awk -way case).

$(parameter:+word)

If parameter is null or unset, nothing is replaced, otherwise it is replaced word word.

So $(PATH:+$(PATH):) expands to: 1) nothing if PATH is null or unset, 2) $(PATH): if PATH is set.

Note. This is for bash.

*1 I just found that scripts like devtoolset-6/enable do use this, $ cat /opt/rh/devtoolset-6/enable # General environment variables export PATH=/opt/rh/devtoolset-6/root/usr /bin$(PATH:+:$(PATH)) ...

I can't speak for other distributions, but Ubuntu has a file, /etc/environment, which is the default search path for all users. Since my computer is only used by me, I put whatever directories I want in my path there unless it's a temporary addition I put into the script.

For me (on Mac OS X 10.9.5) adding the path name (eg /mypathname) to the /etc/paths file worked very well.

Before editing, echo $PATH is returned:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

After editing /etc/paths and restarting the shell, the $PATH variable is added with /pathname . Indeed, echo $PATH returns:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

What happened was that /mypathname was added to the $PATH variable.