Why do I need './' to run Unix commands?

Asked

Viewed 605 times

7

I noticed that every executable that I Gero I need for a ./ to run it on both Linux and Macos (Unix/Unix systems-like). For example, to compile a C file with GCC and run it right away, I do the following commands:

$ gcc fonte.c
$ ./a.out

This also applies when I create a shell script:

$ vim script.sh
$ chmod u+x script.sh
$ ./script.sh

On the other hand, when I do it on Windows, I don’t need to ./ in front. For example, if I create a bat, in the briefcase exemplo, just call the cmd and run the script directly:

$ cd exemplo
$ script.bat

Even when I use the Mingw (like the git bash provided by Sourcetree), which is a more "linked" environment within Windows, I also don’t need the ./. Taking the same example of shell script generation on Linux, on git bash would be so:

$ vim script.sh
$ script.sh

Doubts

  1. Why on more Unix systems do I need for this ./ to run my executables in the current working directory?
  2. Why on Windows I don’t put the ./? (Nor the equivalent .\ in the Windows directory separator notation?)

2 answers

5

First of all this ./ is placed behind the name of your executable to ensure that you are running it within the current directory.

Second, it is a security method to prevent the execution of any harmful program/script that has been housed in the current directory. If there was no need to put ./ it would be possible to place malicious scripts inside a directory with the following designations ls nano vim ps among others, and when to execute ps for example could be executing a completely different command from which you would not know your output.

I think this is basically it, but I am waiting for more answers.

  • On the way :) On the second point of the question, do you have anything to say? Or has MS left a glitch unintentionally and is keeping it by backward compatibility? XD

  • 2

    I think windows does the "search" in the current directory and only then will check the system variable "PATH". But since I never liked the windows shell, I never really cared much, but I’m curious to know if there is any specific reason.

  • 1

    It is by compatibility with DOS, which at the times of the floppy disk had no variable %PATH% — without hard drives, it makes no sense to establish a list of directories to search for executables. Semantics was inherited from version to version until we got here.

  • Interesting view of safety

5


You need it because the current directory is not in PATH. Linux/Unix always looks in the $PATH environment variable. Windows already has a behavior: if it is not on PATH, looks in the current directory, so you don’t need to put the directory before the executable.

Windows does the search in a different way. After separating the command from the arguments and solving the environment variables, the following steps are taken:

  1. if a directory is not passed, find if it is an internal shell command. If you find one, run the command. Otherwise, go to 2;
  2. if a directory is passed, the directory executable will be executed. Otherwise, it will return error to the user;
  3. if a directory is not passed, the current directory command will be executed;
  4. finally, will be sought in the %PATH%.

source: Technet Windows NT- Command Search Sequence

If it bothers you on Linux/Unix, just add PATH=$PATH:. in the file that initializes your environment variables. And you will never need to ./ to run executables.

I’ll leave the file comment /etc/profile.d/z-dot-in-non-root-path.sh from Slackware Current, because there’s an interesting explanation for this.

#!/bin/sh
# Traditionally Slackware has included '.' at the end of the non-root
# $PATH, and kept this behavior long after it had been dropped elsewhere
# due to the relatively low attack risk by having it at (or near) the
# end of the $PATH.  But times have changed, and having this as a default
# violates POLA (principle of least astonishment) just like removing it
# back in the early 90s would have.  So, by default this script is not
# enabled.  If you'd like '.' back at the end of your $PATH for non-root
# users systemwide, make this script executable.  A better choice is
# probably to leave it off and let individual users decide to add it
# in their local profile scripts if they want it.  Even better is just
# to start programs in '.' with ./program, like most of us have been
# doing for years.

# For non-root users, add the current directory to the search path:
if [ ! "`id -u`" = "0" ]; then
 PATH="$PATH:."
fi

In short, this practice violates the POLA in the vision of Slackware developers.

  • 1

    As @lazyFox says in a comment in another reply, actually Windows checks first in the current directory, and afterward tries the directories in the variable %PATH%, in order, if you do not find an executable in the current directory.

  • Thank you @Wtrmute.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.