2

In my opinion, even a simple a.out on the terminal holds complete information about the file being in the current directory. Reiterating it with ./a.out seems superfluous.

Why do we need to specify that the file is in current directory to execute it?

0

3 Answers 3

4

Why do we need to specify that the file is in current directory to execute it?

Shell behavior is standarized by POSIX and there is also security reason for not recognizing executables in the current working directory. And a.out alone does not tell the full story.

Specifically, this is defined as a standard behavior in POSIX standard of Shell Command Language, section Command Search and Execution after all shell-specific expansions and redirections, and built-in lookups have been done:

Otherwise, the command shall be searched for using the PATH environment variable as described in the Base Definitions volume of IEEE Std 1003.1-2001, Chapter 8, Environment Variables:

As for a.out as far as shell is concerned is just a string of text. Depending of how the string of text arranged the shell needs to strip redirections, variable substitutions, and expansions; all what will remain after that is a "command", which may or may not be a built-in. a.out is not a built in in any common shell, so this is where ./ comes to play.

Of course, you can add . to PATH variable and it will work - you will be able to call a.out then. But it is a very bad practice and a security risk: see Is it safe to add . to my PATH? How come?.

In other words, no , it is not superfluous. It's just how shells are supposed to work, and that exists for a technical reason.


side note 1: bash also accepts zero-length field in PATH, according to the manual bash(1):

A zero-length (null) directory name in the value of PATH indicates the current directory.A null directory name may appear as two adjacent colons, or as an initial or trailing colon.

side note 2: Another benefit of using ./ is to avoid confusion with system utilities that share the same name with the local executable. Although in this particular question it specifically talks about a.out executable name (which is automatically assigned when one compiles C code), what would happen if one compiled the code and named the output executable test (i.e, gcc -o test test.c produces executable test and you call test not ./test as command in shell ) ?

The shell would find /usr/bin/test based on /usr/bin being listed in PATH variable and execute that particular binary file, not the executable named test in your current working directory. In fact, I've answered a question about this exact situation before: What is the difference between 'test' and 'test.sh' while running shell scripts?

4

It'll depend on what you $PWD is.

./a.out tells the system to look for the a.out in the present directory as you've provided a path for the file a.out

a.out will only work if $PWD (your present working directory) happens to be in $PATH or the directories searched for binaries.

Your current directory is only searched if it's listed in the search fields, which reduces mistakes & potentially improves security by avoiding mistakes.

3
  • 2
    It's been that way since the 1970s, years before GNU or Linux.
    – guiverc
    Jul 18, 2020 at 3:33
  • 1
    Please note that $PWD is defined as The current working directory as set by the cd command. It does not influence whether or not commands are selected here or elsewhere. However, you are absolutely correct in saying that a.out will work when $PWD is found in $PATH or there are null-length fields in $PATH Jul 18, 2020 at 4:05
  • 2
    Yeah my wording possibly wasn't ideal. If my $PWD is /home/guiverc/bin/ then a.out will be found as /home/guiverc/bin/ is actually in my $PATH, which is what I meant. If however my $PWD is something outside of my $PATH, then it won't be found int the path. Yes it's the cd command which defines what's in $PWD. I didn't feel that was necessary to explain (to readers; maybe I'm wrong)
    – guiverc
    Jul 18, 2020 at 4:37
3

From man bash:

COMMAND EXECUTION
       After a command has been split into words, if it results in a simple command
       and an optional list of arguments, the following actions are taken.

       If the command name contains no slashes, the shell attempts to locate it.
       If there exists a shell function by that name, that function is invoked as
       described above in FUNCTIONS. If the name does not match a function, the
       shell searches for it in the list of shell builtins. If a match is found,
       that builtin is invoked.

       If the name is neither a shell function nor a builtin, and  contains no
       slashes, bash searches each element of the PATH for a directory containing
       an executable file by that name.

In other words, if you call the executable without the leading ./, the shell will search in PATH for a command and can't find the command because the current directory is not in your PATH. If you add the current directory to your PATH, you can call the executable without the leading ./.

Not the answer you're looking for? Browse other questions tagged .