You may have seen how some commands are run by just typing the command name while others require ./command syntax to work. In this short post I'll explain why.
Special Directories . and ..
Everything in Unix is a file. And in addition to regular files there are special files as well. Two examples of them are . (dot) and .. (double dot). These files exist in every directory for easier filesystem navigation. They refer to current and to parent directory.
- . (dot) means current directory
- .. (double dot) means parent directory
So if I'm in my home dir /Users/greys in MacOS, I can use ls command with these dot filenames for accessing my parent directory, which would be /Users:
greys@maverick:~ $ pwd /Users/greys greys@maverick:~ $ ls .. Guest Shared greys unixtutorial
Just to show that it's the same directory, let's do ls /Users:
greys@maverick:~ $ ls /Users Guest Shared greys unixtutorial
greys@maverick:~ $ cd /Users greys@maverick:/Users $ ls Guest Shared greys unixtutorial
In the same way, using . filename is like specifying your current directory.
What ./ Means When Running Commands
Since . means "current directory", ./ simply suggests to your shell that you want to run something from current directory.
Usually you need this when you're writing software and compiling some binaries: before you deploy binaries to their permanent locations, you find them in source code tree and attempt running from there. If everything works okay, you proceed. If something fails – you go back to developing a fix and compiling new binary.
Therefore, ./command syntax is a way of running binary files from the current directory you're in.
Why Do We Need To Use ./ At All?
The reason for having ./command approach at all is because Unix shells are rather strict when it comes to executing files. You see, there's usually this PATH variable that specifies all the directories where executable files may be. So when you're typing any command, your shell looks for it in all the PATH variable directories. And if command isn't there, you get a file not found error.
Unix shell WILL NOT pick up binaries from your current directory as it follows only directories specified in PATH. So that's why the quickest way to run a local command is to specify a full path to it – which means directories and filename – which means ./ for the current directory.
How ./ Command Execution Works
Let's see how it works based on the Hello, World in Golang example I provided recently.
I'm on my becky (Raspberry Pi) system, in my home directory:
greys@becky:~ $ pwd
Here's the PATH user variable value: note how it does not have my /home/greys directory in it.
Here's the hello binary we created using Go:
greys@becky:~ $ ls -al hello -rwxr-xr-x 1 greys tty 871022 Aug 8 23:30 hello
But if I just type hello, this command will not be found and I'll get an error:
greys@becky:~ $ hello -bash: hello: command not found
But when I specify ./ in front of the command, I'm telling my shell: ignore $PATH variable, don't search through available directories. I'm telling you, this binary is right here in my current directory – so don't look and just run it:
greys@becky:~ $ ./hello hello, world
That's it for today! Hope you liked the explanation! Ask me any questions, will be my pleasure to help!