When running scripts in bash, I have to write ./ in the beginning:
$ ./manage.py syncdb
If I don't, I get an error message:
$ manage.py syncdb
-bash: manage.py: command not found
What is the reason for this? I thought . is an alias for current folder, and therefore these two calls should be equivalent.
I also don't understand why I don't need ./ when running applications, such as:
user:/home/user$ cd /usr/bin
user:/usr/bin$ git
(which runs without ./)
Because on Unix, usually, the current directory is not in $PATH.
When you type a command the shell looks up a list of directories, as specified by the PATH variable. The current directory is not in that list.
The reason for not having the current directory on that list is security.
Let's say you're root and go into another user's directory and type sl instead of ls. If the current directory is in PATH, the shell will try to execute the sl program in that directory (since there is no other sl program). That sl program might be malicious.
It works with ./ because POSIX specifies that a command name that contain a / will be used as a filename directly, suppressing a search in $PATH. You could have used full path for the exact same effect, but ./ is shorter and easier to write.
EDIT
That sl part was just an example. The directories in PATH are searched sequentially and when a match is made that program is executed. So, depending on how PATH looks, typing a normal command may or may not be enough to run the program in the current directory.
When bash interprets the command line, it looks for commands in locations described in the environment variable $PATH. To see it type:
echo $PATH
You will have some paths separated by colons. As you will see the current path . is usually not in $PATH. So Bash cannot find your command if it is in the current directory. You can change it by having:
PATH=$PATH:.
This line adds the current directory in $PATH so you can do:
manage.py syncdb
It is not recommended as it has security issue, plus you can have weird behaviours, as . varies upon the directory you are in :)
Avoid:
PATH=.:$PATH
As you can “mask” some standard command and open the door to security breach :)
Just my two cents.
Your script, when in your home directory will not be found when the shell looks at the $PATH environment variable to find your script.
The ./ says 'look in the current directory for my script rather than looking at all the directories specified in $PATH'.
When you include the '.' you are essentially giving the "full path" to the executable bash script, so your shell does not need to check your PATH variable. Without the '.' your shell will look in your PATH variable (which you can see by running echo $PATH to see if the command you typed lives in any of the folders on your PATH. If it doesn't (as is the case with manage.py) it says it can't find the file. It is considered bad practice to include the current directory on your PATH, which is explained reasonably well here: http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html
On *nix, unlike Windows, the current directory is usually not in your $PATH variable. So the current directory is not searched when executing commands. You don't need ./ for running applications because these applications are in your $PATH; most likely they are in /bin or /usr/bin.
This question already has some awesome answers, but I wanted to add that, if your executable is on the PATH, and you get very different outputs when you run
./executable
to the ones you get if you run
executable
(let's say you run into error messages with the one and not the other), then the problem could be that you have two different versions of the executable on your machine: one on the path, and the other not.
Check this by running
which executable
and
whereis executable
It fixed my issues...I had three versions of the executable, only one of which was compiled correctly for the environment.
Rationale for the / POSIX PATH rule
The rule was mentioned at: Why do you need ./ (dot-slash) before executable or script name to run it in bash? but I would like to explain why I think that is a good design in more detail.
First, an explicit full version of the rule is:
if the path contains / (e.g. ./someprog, /bin/someprog, ./bin/someprog): CWD is used and PATH isn't
if the path does not contain / (e.g. someprog): PATH is used and CWD isn't
Now, suppose that running:
someprog
would search:
relative to CWD first
relative to PATH after
Then, if you wanted to run /bin/someprog from your distro, and you did:
someprog
it would sometimes work, but others it would fail, because you might be in a directory that contains another unrelated someprog program.
Therefore, you would soon learn that this is not reliable, and you would end up always using absolute paths when you want to use PATH, therefore defeating the purpose of PATH.
This is also why having relative paths in your PATH is a really bad idea. I'm looking at you, node_modules/bin.
Conversely, suppose that running:
./someprog
Would search:
relative to PATH first
relative to CWD after
Then, if you just downloaded a script someprog from a git repository and wanted to run it from CWD, you would never be sure that this is the actual program that would run, because maybe your distro has a:
/bin/someprog
which is in you PATH from some package you installed after drinking too much after Christmas last year.
Therefore, once again, you would be forced to always run local scripts relative to CWD with full paths to know what you are running:
"$(pwd)/someprog"
which would be extremely annoying as well.
Another rule that you might be tempted to come up with would be:
relative paths use only PATH, absolute paths only CWD
but once again this forces users to always use absolute paths for non-PATH scripts with "$(pwd)/someprog".
The / path search rule offers a simple to remember solution to the about problem:
slash: don't use PATH
no slash: only use PATH
which makes it super easy to always know what you are running, by relying on the fact that files in the current directory can be expressed either as ./somefile or somefile, and so it gives special meaning to one of them.
Sometimes, is slightly annoying that you cannot search for some/prog relative to PATH, but I don't see a saner solution to this.
When the script is not in the Path its required to do so. For more info read http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html
All has great answer on the question, and yes this is only applicable when running it on the current directory not unless you include the absolute path. See my samples below.
Also, the (dot-slash) made sense to me when I've the command on the child folder tmp2 (/tmp/tmp2) and it uses (double dot-slash).
SAMPLE:
[fifiip-172-31-17-12 tmp]$ ./StackO.sh
Hello Stack Overflow
[fifi#ip-172-31-17-12 tmp]$ /tmp/StackO.sh
Hello Stack Overflow
[fifi#ip-172-31-17-12 tmp]$ mkdir tmp2
[fifi#ip-172-31-17-12 tmp]$ cd tmp2/
[fifi#ip-172-31-17-12 tmp2]$ ../StackO.sh
Hello Stack Overflow
In OSX, I have added a new path to /etc/paths. It is a path to a medical image viewer application known as rview.
It seems to clash with vim and on typing rview in bash it starts up vim.
But my question is more general, how do you differentiate applications with the same names included in PATH?
The path is evaluated in order; the first matching executable is run.
To edit this, you should change your user profile, not the system-wide configuration. You may have a line similar to this in your ~/.bash_profile file:
export PATH=/usr/local/sbin:/usr/local/bin:$PATH
Just add the path to your application before $PATH and it should work fine. If the line isn't there, create it.
And, if you really want to edit the system paths, just add yours at the top of /etc/paths instead of the bottom.
I tried to make iverilog command s.t I can run verilog program on my Macbook Air.
After few steps for installing the files, the tutorial told me to type:
export PATH=~/bin:/usr/local/iverilog/bin
It worked in terms of iverilog command, i.e, I can compile .v file. However, normal command like ls, man,etc.
I guess it is the problem of the PATH of the command sets, which means those normal unix command is not located.
Can someone tell me how to fix it and I dont need to export the PATH everytime?
You didn't add your paths to the current paths established by the OS. Instead, you replaced it with your paths. This is what you need to do in order to add paths to your PATH variable:
export PATH=$PATH:~/bin:/usr/local/iverilog/bin
The $PATH part is your current PATH value, which is added (concatenated actually) to the list of new paths you want to add. This is turn is assigned to PATH variable.
To make this additions permanent, you may want to add the above line to the end of your .profile file, or .bash_profile (whatever you have in OS X)
You can also do as this:
http://architectryan.com/2012/10/02/add-to-the-path-on-mac-os-x-mountain-lion/
Which says that you can edit the file /etc/paths and add whatever paths you want to add, one per line, then save that file and your added paths are available. In this case, just remember to use absolute paths. That is, paths starting with / . The first one you use: ~/bin is not an aboslute path. You need to convert it to an absolute path. To do this, remember that ~ is a shortcut to your HOME directory: something like /Users/myloginname. Type echo $HOME to find it out.
In order for me to run a .exe or a .sh in Cyqwin, I have to put a ./ at the beginning of my line. Is there a way for me to change this so that isn't necessary? This is causing problems when I try and run a test script and it can't find files that are right in the directory I'm working in.
The reason you must use a './' is to specifically tell the shell what file you are trying to execute. Without the leading './', your $PATH environment variable is searched. You can try adding the directories with scripts and executables you commonly use to your $PATH if you'd like. Alternatively, you can add the current directory (.) to your $PATH, but this is a Very Bad Idea as it can lead to unintentional executions.
From the cygwin environment variables doc:
The PATH environment variable is used by Cygwin applications as a list
of directories to search for executable files to run. This environment
variable is converted from Windows format (e.g.
C:\Windows\system32;C:\Windows) to UNIX format (e.g.,
/cygdrive/c/Windows/system32:/cygdrive/c/Windows) when a Cygwin
process first starts. Set it so that it contains at least the
x:\cygwin\bin directory where "x:\cygwin is the "root" of your cygwin
installation if you wish to use cygwin tools outside of bash.
I am looking to enable my terminal with the MacVim/mvim command so that I can access macvim through the terminal.
Following directions, I have downloaded and unzipped the MacVim files.
To be able to access MacVim through the terminal, one requires to set the VIM_APP_DIR environment variable with the value being the location of mvim script or the MacVim path.
By attempting the following command:
export VIM_APP_DIR = "the filepath"
I carried out printenv and VIM_APP_DIR does not exist in the set of environment variables.
Now that sounds more like a problem within a problem. The problem is I am unable to find a way to enable my Mac OS X Lion to be Vim powered and the above was the recommended route towards glory, however leave glory, the actor wasn't even there (VIM_APP_DIR).
First, you may not have to set the VIM_APP_DIR environment variable if you put the MacVim.app bundle in one of the “usual” locations:
~/Applications/ (the Applications folder in your home directory)
/Applications/ (the main Applications folder on the computer)
/Applications/Utilities/
It actually checks a few more locations, too: some relative to the location of the mvim script, and in a vim/ directory under the described directories.
In most cases, you should only need to set VIM_APP_DIR if mvim complains like this:
Sorry, cannot find MacVim.app. Try setting the VIM_APP_DIR enviro
nment variable to the directory containing MacVim.app.
Second, if you have to set VIM_APP_DIR (because you keep MacVim.app in an “unusual” location), the value of the environment variable should be the directory that contains MacVim.app, not the location of MacVim.app or mvim itself.
For example: If, you moved MacVim.app to /MyFavoriteApps/MacVim.app and have mvim available somewhere in your PATH, then you would need to set VIM_APP_DIR to /MyFavoriteApps (not /MyFavoriteApps/MacVim.app).
Third, in bash (the shell you are probably using), parameter assignments must not have spaces around the equal sign. It should look like this:
export VIM_APP_DIR=/MyFavoriteApps
If the pathname has spaces or special characters, then you may need to quote it. Single quotes are a good choice because they represent a literal string (you can include any character except a single quote itself).
export VIM_APP_DIR='/My Favorite Apps'
Last, you will probably want to put this “assignment and export” in your shell’s initialization file to make sure the value is set in all your future shell instances. A good choice is usually ~/.bashrc.
I don't know where you're getting this from. All that is required is to put the mvim script in your path, e.g., /usr/local/bin, and MacVim.app in a "normal" location such as /Applications or ~/Applications. Full list here: https://github.com/b4winckler/macvim/blob/master/src/MacVim/mvim (line 20).