The literal answer is as others have given: because the current directory isn’t in your
But why? In short, it’s for security. If you’re looking in someone else’s home directory (or /tmp), and type just
ls, you want to know you’re running the real one, not a malicious version your prankster friend has written which erases all your files. Another example would be
[, which might override those commands in shell scripts, if your shell doesn’t have those as built-ins.
. as the last entry in your path is a bit safer, but there are other attacks which make use of that. An easy one is to exploit common typos, like
ls-l. Or, find a common command that happens to be not installed on this system —
vim, for example, since sysadmins are of above-average likelyhood to type that.
Does this sound too theoretical? It largely is, but it definitely can happen in reality, especially on multi-user systems. In fact, here is an example from this site where an administrator switched to a users’ home directory and found
ps to be masked by an executable of that name.
In Linux, UNIX and related operating systems,
. denotes the current directory. Since you want to run a file in your current directory and that directory is not in your
$PATH, you need the
./ bit to tell the shell where the executable is. So,
./foo means run the executable called
foo that is in this directory.
You can use
which to get the full path of any commands found in your
If you mean, why do you need ./ at the start – that’s because (unlike in Windows), the current directory isn’t part of your path by default. If you run:
your shell looks for
ls in the directories in your PATH environment variable (
echo $PATH to see it), and runs the first executable called
ls that it finds. If you type:
the shell will do likewise – but it probably won’t find an executable called a.out. You need to tell the shell where a.out is – it it’s in the current directory (.) then the path is
If you’re asking why it’s called “a.out”, that’s just the default output file name for gcc. You can change it with the -o command line arg. For example:
$ gcc test.c -o test $ ./test