Why do we use "./" (dot slash) to execute a file in Linux/UNIX?
The literal answer is as others have given: because the current directory isn't in your $PATH
.
But why? In short, it's for security. If you're looking in someone else's home directory (or /tmp), and type just gcc
or 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 test
or [
, which might override those commands in shell scripts, if your shell doesn't have those as built-ins.
Having .
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 sl
or 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 type
or which
to get the full path of any commands found in your $PATH
.
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:
$ ls
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:
$ a.out
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 ./a.out
.
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