I'm messing around with commands, but where are the commands? I often hear it through the PATH, but what does that mean? This article was written for beginners who thought about that. I don't read the command code.
By the way, I tried each command on Mac and zsh, but it is similar on Unix.
To conclude earlier, passing through PATH means ** registering the location of an external command in the command search path so that the external command can be executed without specifying it in the path **. Details are described below.
The commands include ** internal commands (built-in commands) ** built into the shell and ** external commands ** that are placed as files under a specific directory, as shown below.
Let's try the location of the ls
command with the which
command.
$ which ls
output:
/bin/ls
Apparently it's right under / bin
.
Now let's look inside / bin
.
$ ls /bin
output:
[ chmod dash df expr ksh ln mv pwd sh sync unlink
bash cp date echo hostname launchctl ls pax rm sleep tcsh wait4path
cat csh dd ed kill link mkdir ps rmdir stty test zsh
There is a file with the same name as the command you use often.
If you take a look at the contents of the ls
command, you can see that it is a ** binary file **.
$ od -h /bin/ls | more
output:
0000000 facf feed 0007 0100 0003 0000 0002 0000
0000020 0013 0000 0710 0000 0085 0020 0000 0000
0000040 0019 0000 0048 0000 5f5f 4150 4547 455a
0000060 4f52 0000 0000 0000 0000 0000 0000 0000
(Abbreviation)
Internal commands are loaded into memory when the computer starts, but ** external commands exist as files on disk (such as under / bin
) and are loaded from disk every time **.
In other words, when executing an external command, you can ** specify the direct path to execute the external command **.
** Example: Execute the ls command by directly specifying the location of the file **
$ /bin/ls
You can execute the command as above, but it is troublesome, so an environment variable called PATH
is prepared.
This is strictly called ** command search path (command search path) **.
Even if you do not specify the path directly, the program searches the command search path without permission, so you can execute the ls
command as shown below.
$ ls
To see the contents of PATH
once, use the ʻecho command to look at
PATH`.
$ echo $PATH
output:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin
Looking at the results, some directories were output separated by :
.
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/Library/Apple/usr/bin
These indicate the location (path) of the external command.
If you try to execute a command that does not pass PATH
or does not exist, you will get the following.
** Example: for zsh **
zsh: command not found: hogehoge
If you should have already entered the command, but it says not found
, etc.
Often the PATH
does not pass.
What you do to pass PATH
is to add the path of the directory where the command you want to use is placed to the ** environment variable PATH
. ** **
For example, if you want to use the php
command under / hogehoge / bin
Add / hogehoge / bin
to the environment variable PATH
.
Try adding it using the ʻexport` command.
$ export PATH="/hogehoge/bin:$PATH"
Check if it was added with ʻecho`. (You can also try the added command)
$ echo $PATH
output:
/hogehoge/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin
As mentioned above, you can add environment variables using the ʻexport command, but it is troublesome to add them using the ʻexport
command one by one, so basically ** in the configuration file of the shell you are using Append. ** **
This will automatically overwrite PATH
when you start the shell.
** Example: for zsh **
Add using ʻexport in the
.zshrc` file under the HOME directory.
.zshrc
export PATH="/hogehoge/bin:$PATH"
At the end, I wrote $ PATH
, which expands the existing environment variable PATH
. In other words, it has the same meaning as:
.zshrc
export PATH="/hogehoge/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
At this time, if you completely overwrite the existing one, ** various commands will not be usable, so be careful. ** ** For example, if you do the following, commands such as under ** / bin will not be read. ** **
.zshrc
export PATH="/hogehoge/bin"
As mentioned above, the environment variable PATH
makes it possible to execute a predetermined external command without directly specifying the path.
If you don't know about the shell config file, you can check the shell you are using and google how to write it.
PATH
has priority.
For example, in the following cases, it is read in order from / hogehoge / bin
on the left.
PATH=/hogehoge/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin
For example, if you have the commands php
in / hogehoge / bin
and / use / local / bin
respectively
$ php
If you execute, it will be the php
command of / hogehoge / bin
.
As you can see, when you specify PATH
, you also need to be careful about the priority.
The location of external commands is standardized by FHS (Filesystem Hierarchy Standard) in the form of ** "Let's put these commands in this location!" **.
This makes it clear at a glance that no matter what Linux system you play with, "this / bin
directory contains core commands that can be used even in an emergency. "
(However, although it is standardized, it is not enforced, so strange commands may be in strange places for each OS)
I have summarized the locations of the external commands standardized by these and the differences between them in the table below, but let's look at each one.
directory | Single user mode | Summary |
---|---|---|
/bin | available | The one that can be used even in an emergency |
/usr/bin | out of service | General guy |
/usr/local/bin | out of service | A self-made script |
/sbin | available | Requires superuser (root) privileges |
/usr/sbin | out of service | Requires superuser (root) privileges |
/bin Place the ** most core external commands ** that can be used in single user mode under this directory. Single-user mode is used in an emergency such as when the OS cannot boot normally.
As I confirmed at the beginning, the following command was included in the / bin
of my Macbook Pro.
[ chmod dash df expr ksh ln mv pwd sh sync unlink
bash cp date echo hostname launchctl ls pax rm sleep tcsh wait4path
cat csh dd ed kill link mkdir ps rmdir stty test zsh
If you don't know about these commands, you can look them up and find that they are all simple and important.
/usr/bin Instead of using it in single user mode, basically put commands managed by the package manager (package management system). There are various package managers for each OS, but I will not mention them here. Look in the directory on your machine to see what commands are actually available.
/usr/local/bin Put commands that are not used in single user mode and are not managed by the package manager.
By the way, homebrew, which is a package manager familiar to Mac users, Use this directory. You can find out why homebrew uses this location on the homebrew page.
https://docs.brew.sh/FAQ#why-does-homebrew-prefer-i-install-to-usrlocal
Translated, it says:
Apple has assigned this directory for non-system utilities. This means that by default there are no files in / usr / local so you don't have to worry about ruining your existing or system tools.
It is basically treated the same as the directory of each hierarchy above, but unlike bin
, it puts administrative commands that the system administrator can mess with.
These are not available to regular users as they require superuser (root) privileges.
As I wrote earlier, the conclusion is
To pass the PATH means to register the location of the external command in the command search path so that the external command can be executed without specifying it in the path.
It was that.
I didn't find many articles that mention internal commands and external commands while passing through the PATH, so I wrote this time.
Recommended Posts