13

This is the output from ls -all command :

-rwxr----- 1 subhrcho dba  3600 Nov 13 17:26 jdev
-rw-r----- 1 subhrcho dba  1566 Nov 13 17:26 jdev-Darwin.conf
-rw-r----- 1 subhrcho dba   347 Mar  6  2009 jdev-debug.boot
-rw-r----- 1 subhrcho dba   821 Nov 13 17:26 jdev-logging-debug.conf
-rw-r----- 1 subhrcho dba   584 Nov 13 17:26 jdev-logging.conf
-rw-r----- 1 subhrcho dba  4717 Jul 31 16:09 jdev.boot
-rw-r----- 1 subhrcho dba 12877 Nov 13 17:26 jdev.common
-rw-r----- 1 subhrcho dba  5047 Dec  6 01:43 jdev.conf
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdev.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64W.exe
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdevW.exe

Now when I just run jdev it runs a different version of Oracle JDveloper than when I run it as ./jdev..Why is it so ?

0

4 Answers 4

20

When you run an executable file ( or rather in unix/linux world - a file with executable rights/flag on) like so :

$ ./jdev

you then mark with . that you want to run a file inside your working directory (directory that you are currently in) that is named jdev and has executable rights for the user that is launching it (you have to note that it can still be a link to other file, you can check that by typing ls -l jdev in the terminal)

( see file permissions in linux/unix )

When you run it as

$ jdev

then most likely there is jdev installed somewhere on the system and you have it in $PATH ( e.g. /usr/bin/ or /bin/ or /usr/local/bin/ )

As peterph stated : you can use which to to point the executable that is being launched with particular command, e.g.:

$ which find
/usr/bin/find
5
  • 1
    Also not that the which utility can tell you what executable will be used if no path is given.
    – peterph
    Jan 22, 2013 at 9:29
  • @peterph Edited my answer.
    – Patryk
    Jan 22, 2013 at 9:43
  • 7
    It's much better to use type to check what is launched by particular command. Cause which will show you just a binary somewhere in the $PATH, however it may be aliased to absolutely another binary.
    – rush
    Jan 22, 2013 at 9:44
  • @rush I has just tried that and it won't work as you say: [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelim. While zsoelim -> soelim
    – Patryk
    Jan 22, 2013 at 9:48
  • 2
    @Patryk I think rush meant the shell aliases/functions, which which has no chance of finding, since it is a standalone binary that doesn't have access to the running shell environment (by which I mean aliases and functions, not just the environment variables, some of which are inherited).
    – peterph
    Jan 22, 2013 at 9:58
9

If you call a command with no slash in its name in a shell then, it's looked up in the shell aliases, functions and in the list of paths provided in the $PATH environment variable. (note that you can have the current working directory (specified as . or the empty string) or any relative directory in $PATH, but that's not recommended for security reasons).

If there's a slash in the name, then that doesn't happen, the name is taken as a path to execute the command from (though some shells like zsh allow aliases or functions to have slashes in their name which would then take precedence).

So, if you want to run a command called foo that is in the current working directory, you have to come up with a name that contains a slash. ./foo is the most obvious. You could also use the full path, or ../dir/foo...

To know what the shell would run, use the type command. Do not use the which command which generally doesn't do what you think it does and is a heritage from csh which is better left alone.

4
2

I recommend to use Zsh's built-in 'where' (better than 'which') to see how and in which order aliases, shell built-ins or anything else will be found in order to $PATH ;-)

Here is an example to understand things better, how it is chosen:

[ 0:04:08 ] afsin@s15426859:~ % pwd
/home/afsin
[ 0:04:30 ] afsin@s15426859:~ % which who
/usr/bin/who
[ 0:04:47 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:27 ] afsin@s15426859:~ % echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/afsin/bin
[ 0:05:31 ] afsin@s15426859:~ % touch who
[ 0:05:40 ] afsin@s15426859:~ % chmod +x who
[ 0:05:47 ] afsin@s15426859:~ % ls -al who
-rwxr-xr-x 1 afsin afsin 0 23. Jan 00:05 who
[ 0:05:50 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:55 ] afsin@s15426859:~ % export PATH=$PATH:.
[ 0:06:09 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:14 ] afsin@s15426859:~ % alias who=who
[ 0:06:19 ] afsin@s15426859:~ % where who
who: aliased to who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:22 ] afsin@s15426859:~ % which who
who: aliased to who
[ 0:06:27 ] afsin@s15426859:~ %
1

Although this probably depends on your shell, the rule usually is:

  • If you provide a path, either relative or absolute, that path is used. ./jdev is a relative path, because . stands for the current directory (in fact, ls -all . would give you the same as ls -all). If you do /usr/bin/tool/, you are using an absolute path. In these cases, the file pointed to is executed.

  • If you do not provide a path, but just a name, the directories in $PATH are searched for the tool you're trying to run.

If you have a file in the current directory with the same name as a file in some of the directories in $PATH, and you run it by prepending ./ to its name, you will effectively run a different file.

Perhaps another issue is that you were actually expecting jdev to run the executable in the current directory. Unless you changed $PATH to include ., this is not something you should expect at all...

... and it is still a not so good idea to include . there, if you do so please at least put it at the end, so that the rest of $PATH is always searched first — just imagine that you are on a shared network directory and someone decides to put an evil binary there as ls, if $PATH starts with ., a simple ls -lah will be enough to attack your system.

1
  • Your terminology is confusing. jdev alone is also a relative path. The rule is: if it doesn't contain a slash, then it's looked up in aliases, functions and $PATH, otherwise, it's looked up directly on the file system (though some shells allow aliases or functions with / in their name which would then take precendence). Jan 22, 2013 at 10:23

You must log in to answer this question.

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