What does it mean to go through the PATH? Where are the commands?

Overview

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.

Conclusion

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.

Internal and external commands

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.

パッケージ管理マネージャ.png

Where is the ls command?

Let's try the location of the ls command with the which command.

$ which ls

output:

/bin/ls

Apparently it's right under / bin.

What's in / 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.

The substance of the external command is a file

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)

To execute an external command

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

The contents of PATH are directories with external commands.

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 the PATH does not pass

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.

To pass the PATH

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 priority

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.

Differences in the location of each command (/ bin, / usr / local / bin, etc.)

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.

/ sbin and / usr / sbin

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.

Summary

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

What does it mean to go through the PATH? Where are the commands?
python note: What does it mean to set a seed with random number generation?
What does the last () in a function mean in Python?
I wrote it in Go to understand the SOLID principle
What to do if the user name is changed and the pyenv library path does not pass
What to do when the jupyterlab extension settings are not reflected
If you try to start the jupyter notebook installed with pip and it says "command not found", it seems that you can go through the PATH.