3

I have a binary file named hello2 in my current working directory.

To execute it I need to press ./hello2 and it shows the output.

But when I use the following command ././hello2 it still works.

Can you please explain how the shell is interpreting this command?

alamin
  • 425

3 Answers3

8

When you run the command

$ ./hello2

the shell looks up the file hello2 in the directory ., i.e. in the current directory. It then runs the script or binary according to some rules (which are uninteresting in this context).

The command

$ ././hello2

also causes the shell to execute the file.

This is because . and ./. is the same directory.

Every directory has a . directory entry. This entry corresponds to the directory itself. So saying ./ is the same as saying ././ and ././././ etc.

The only difference is that the system might have to do a few extra directory lookups (unless the shell is smart and spots the obvious simplification).


Every directory also has a .. entry which points to its parent directory.

This means that if the current directory is called alamin, then the following would also execute the file:

$ ../alamin/hello2

as would

$ ../alamin/./hello2

and

$ .././alamin/./hello2

The root directory, /, is a special case. Its .. directory entry is the same as its . directory entry. This means that you can't go "above" it with /...

See also: The number of links for a folder doesn't reflect the real status?

Kusalananda
  • 333,661
  • thanks for the edit. I got what I needed.... Thanks.... (y) – alamin Sep 01 '17 at 15:12
  • "Every directory also has a .. entry which points to its parent directory." – And if that directory is /, it is its own parent. – Jörg W Mittag Sep 01 '17 at 17:21
  • @JörgWMittag Thanks. Added a note about that too. – Kusalananda Sep 01 '17 at 17:27
  • And you can even have .. in the middle of a path! So ~/Documents/../Pictures/ points to the same location as ~/Pictures/. It's just a more confusing way to point to ~/Pictures/ – zck Sep 01 '17 at 18:37
  • 3
    @zck ... unless ~/Documents/ is a link. – maaartinus Sep 01 '17 at 19:27
  • 1
    Links and .. act a little strangely. The actual, low-level fact is that going into .. inside a link goes to the parent of the directory the link points to. If par/dir, link -> par/dir, then link/.. is par. This is what you'd expect from the above rules. Shells like bash "helpfully" interpret .. specially. They keep track of which path you took to a directory instead of just which directory it is. If you cd into link, and then cd into .., you'll actually cd into . instead of par. – HTNW Sep 01 '17 at 20:12
  • @HTNW: cd -P uses the physical structure: it resolves symlinks before processing instances of ... Run help cd for more. IIRC, there's a shell option to make that behaviour the default, instead of -L. – Peter Cordes Sep 01 '17 at 22:18
3

When typing the name of a command, say hello, the system looks for the file in your PATH, which should look somehow like this:

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

If the system can't find the command in those directories, you'll get a command not found error.

By prepending ./ to the command, you are saying to limit the search to the current directory.

Every directory has an entry ., corresponding to the directory itself, so all you are doing by typing ././hello is still limiting the lookup of the command in the directory itself (twice).

Try to cd ./././././.

resc
  • 1,224
  • 10
  • 19
  • 2
    I believe the system only looks up the command in the PATH if the command is a bare name, no directory in front of it. By typing ./hello, you bypass looking up 'hello' in the path. – Justsalt Sep 01 '17 at 17:43
  • @Justsalt makes a highly underrated point. As file paths, hello and ./hello mean exactly the same thing, and both would work fine if you asked the kernel to execute them. However, the shell only asks the kernel to do this when the name contains a /, so we input ./hello merely because it's the shortest path to the file that happens to contain a / (and therefore easiest to type) – that other guy Sep 01 '17 at 22:19
1

The answers are correct, but I would like to tell you a different thing. Run the following command,

┌─[luvpreet@DHARI-Inspiron-3542] - [~/Desktop/drf-vogo] - [2017-09-01 08:57:42]
└─[0] ls -la
total 60
drwxrwxr-x 14 luvpreet luvpreet 4096 Aug 14 15:30 .
drwxr-xr-x 21 luvpreet luvpreet 4096 Sep  1 00:27 ..

You will notice that, first 2 lines, they have . and ..

Now, this . is the pointer to the very current directory you are in. And .. is the pointer to it's parent directory .

When you do cd ..,

monitoring-server@monitoring-server:~/kibana-project$ cd ..
monitoring-server@monitoring-server:~$ 

It moves to the parent directory.

When you do cd .,

monitoring-server@monitoring-server:~/kibana-project$ cd .
monitoring-server@monitoring-server:~/kibana-project$ 

It remains in the same directory.

Now, ../testfile.txt, is pointing to the testfile.txt file in the parent directory. And ./testfile.txt is pointing to the testfile in the current directory.

Therefore, ././././././././, as much as possible, it remains in the same directory.

And ../../../../ will keep going 1 level up to the parent directory.