Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

While executing a C program, a.out, using the Ubuntu terminal, why do I always need to type ./ before a.out, instead of just writing a.out? Is there solution for this?

share|improve this question
    
a bit further info: the dot is shorthand for 'source', which is a builtin command of the bash shell. more about the command can be obtained through review of 'man bash'. –  nathan Jul 16 '13 at 21:02
8  
@nathan no it's not, the . in this example is current working directory. The source shorthand is . file.sh i.e. with a space, not a /. You cannot source a compiled program: ELF != bash... –  tobyodavies Jul 16 '13 at 22:56
    
@tobyodavies thanks for clarifying - indeed i was confused about the differences between ./ and . –  nathan Jul 17 '13 at 0:40
    
This MUST be a duplicate. This is the very first thing everyone runs into when creating their own program on UniX/Linux. –  Peter Mortensen Jul 17 '13 at 22:44
    

10 Answers 10

When you type the name of a program such as a.out the system looks for the file in your PATH. On my system, PATH is set to

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Yours is probably similar. To check, enter echo $PATH in a terminal.

The system looks through these directories in the order given and if it can't find the program produces a command not found error.

Prepending the command with ./ effectively says "forget about the PATH, I want you to look only in the current directory".

Similarly you can tell the system to look in only another specific location by prepending the command with a relative or absolute path such as:

../ means in the parent directory eg ../hello look for hello in the parent directory.

./Debug/hello : "look for hello in the Debug subdirectory of my current directory."

or /bin/ls : "look for ls in the directory /bin"

By default, the current directory is not in the path because it's considered a security risk. See Why is . not in the path by default? on Superuser for why.

It's possible to add the current directory to your PATH, but for the reasons given in the linked question, I would not recommend it.

share|improve this answer
20  
This. +1 Do not add . to your PATH (as the other 2 answers currently suggest) due to the security risk mentioned in this answer. –  Day Jul 16 '13 at 17:20
7  
It may also be worth noting that there is nothing special about . here, you can use a full or relative path to an executable e.g. /home/user/foo/a.out or ./build/a.out –  tobyodavies Jul 16 '13 at 22:57
    
@tobyodavies; Actually . is special because it means "my current directory" an so could be any directory the user finds them self in with read and execute privileges. This is potentially more dangerous than adding a specific fully qualified path. –  Warren Hill Jul 17 '13 at 6:15
    
@WarrenHill when considering adding it to your path, yes it is quite different. However in terms of bash syntax, . holds no special status, it's just a path that could just as well start with / and ./blah would work just as well with cat or grep as a bash prompt. –  tobyodavies Jul 17 '13 at 6:26
    
@tobyodavies: OK I've edited my answer to include your point. –  Warren Hill Jul 18 '13 at 5:56

The reason for this is simple.

Suppose you have a command with the same name as an application in the current directory. Then running the command in the shell would invoke your app instead of the built-in command. This would be a security concern if nothing else.

By requiring ./ to be used in front, the shell knows that you want to execute the application with the given name and not a built-in command with that name.

share|improve this answer
    
Thanks George. Thanks makes sense (and I think I heard a few years back -- need to stick with Linux long enough this time for this stuff to sink in) –  Doug Dec 16 '10 at 3:28

./ executes files that are not in your $PATH, rather it executes the file in the current directory (or another via ./home/stefano/script.sh). Now, PATH is an environment variable that contains all of the places where bash can look for executable programs, without having the full (absolute) path to them.

This seperation is needed to avoid running the wrong file. I.e. if you have a file called ls in your home directory, it not being in your PATH will prevent bash from confusing it with the real ls. The PATH variable also defines the search order:

  • When you run a command, or a program tries to make an exec syscall (a special method of the Kernel, how programs are started), the system looks for the file by going through each of the directories in your PATH. Once the program has been found, even if it's in multiple directories, the search is interrupted and the first one found is run.

To run a file, you will need to set the executable bit in the permissions:

  • Since you're already on the command line, you can just type chmod +x finename.

  • Or you can set the permissions by right clicking the file and selecting Properties:

    alt text

You can now copy the file to any of the directories in PATH, to see which ones are in there - and they're set on a per-user basis - type echo $PATH.

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

If you create an executable file, cat, and move it to /usr/local/sbin, it is run instead of the proper cat, which resides in /bin. You can find out where your files are by using type cat and whereis cat.

share|improve this answer
2  
One thing to note: his question seems to indicate that he has compiled and linked something with gcc, which automatically sets the execute bit. –  Nathan Osman Dec 16 '10 at 3:36

Why do you need to type ./ before executing a program?

In the terminal, whenever you type the name of an application, let's say gedit, the terminal will go look in some (pre-defined) directories that contain applications (the binaries of the applications). The names of these directories are contained in a variable called PATH. You can see what's in this variable by executing echo $PATH. See those directories separated by :? Those are the directories that the terminal will go search in, if you just type gedit, nautilus, or a.out. As you can see, the path of your a.out program is not there. When you do ./a.out, you're telling the terminal "look in the current directory, and run a.out, and don't go look in PATH.

Solution 1

If you don't want to type ./ every time, you'll need to add a.out's directory in $PATH. In the following instructions, I'll assume that the path to a.out is /path/to/programs/, but you should change it to your actual path.

  1. Simply add the following line to the end of the file ~/.pam_environment:

    PATH DEFAULT=${PATH}:/path/to/programs
    

    Source: Persistent environment variables

  2. Log out and log back in. You'll now be able to run a.out without ./ from any directory.

If you have other programs in other directories, you can just add those to the above line. However, I'd advise to have one directory called "myPrograms" for example, and put all of your programs under it.

Solution 2

Note: change userName to your actual Ubuntu username.

What if you have other programs you want to run? And they're all in different folders? Well, a "more organized" solution would be to create a folder called bin under your Home directory, and add symbolic links (shortcuts) under that folder. Here's how:

  1. mkdir /home/userName/bin

    • This will create the folder bin under your Home directory.
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • This will create a "symbolic link" (basically, a shortcut) of your a.out program under bin.
  3. Log out and log back in. You'll now be able to run a.out without ./ from any directory.

Now, whenever you have another program anywhere else, let's say the program b.in on your Desktop, all you need to do is: ln -s /home/userName/Desktop/b.in /home/userName/bin, and you'll then be able to run it without ./ as well.

Note: thanks to @Joe's comment, when you do backups, symbolic links have to be handled specially. By default, rsync doesn't process them at all, so when you restore, they're not there.

share|improve this answer
1  
This is a handy trick if it is used sparingly. Using it a lot makes your system do things that someone else would not expect. Also, when you do backups, symlinks have to be handled specially. By default, rsync doesn't process them at all, so when you restore they're not there. –  Joe Jul 17 '13 at 19:10

As George pointed out in his answer, this helps you note that your executing a file in the current working directory (pwd).

I remember asking this question to my senior a long time ago, he said I should add . to my path so that when I do a.out it looks in the current directory and executes that. In this case I don't have to do ./a.out.

But, personally, I'd recommend against it. It never happened to me, but if you are on an alien network directory or something, and a malicious executable file called ls exists there, then having . in your path is a very bad idea. Not that you will run into this problem very often, just saying.

share|improve this answer
    
ok, Stefano adopted his answer to contain this info :) –  Shrikant Sharat Dec 16 '10 at 3:34
2  
I completely agree with not adding . to $PATH. Very dangerous idea. –  Nathan Osman Dec 16 '10 at 3:37

A './' makes sense when you run a program that is known for you and specific, e.g. your own one. This program must be present in your current directory. A './' makes no sense when you run a standard command that is somewhere in the $PATH. A command "which command-to-run" tells you where the command-to-run is in the $PATH.

share|improve this answer
$ gcc hello.c -o /path/to/someplace/hello

will produce an executable in some location. If that location is on your path, you will be able to run the file. You can script this if you like to create a label for the action "compile this source code using the gcc and place an executable at some location that is on your path"

I would suggest you create a new directory called "testbin" or something of that sort and put it on your path to keep your existing path directories clean.

share|improve this answer

./ eliminates unnecessary search for a path. ./ force to search in the current directory only. If we don't give ./ then it will search various path set into the system like /usr/bin, /usr/sbin/, etc.

share|improve this answer

"./" means you want to execute a file in the current directory its a shortcut for typing the whole path for example:

[root@server ~]#/path/to/file/file.pl

is same as :

[root@server file]#./file.pl

in the previous example you went through the directory and its sup-directories to the file location and used "./" to run the file in the current directory.

the one before it "[root@server ~]#/path/to/file/file.pl" also will execute the file if you lazy to "cd" your way to the file location.

share|improve this answer

It's very simple and has many uses.

  1. When multiple versions of same application is installed, it will be available in different path but a soft link to your binary can be created in /usr/bin. For example, Python 2.7, Python 2.6 is installed but /usr/bin/python -> python2.7 /usr/local/bin/python -> python2.6

If you are in the path /usr/local/bin and executes Python it will always execute Python 2.7. Specifying . will take the current folder's executable.

  1. . - always represents execute from the current directory. And .. always means executes from the previous directory.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.