Different ways of executing binaries and scripts

The following commands are the same, a dot component means "current directory". To allow for being executed, the files need to have executable permissions:

path/to/binary
./path/to/binary

Note that if a path does not contain a slash, it is treated as a command (either a shell built-in or a program that is looked up in the $PATH environment variable).

The following are almost the same, they execute a shell script (not a binary!) in the current shell environment. A small difference between the two lines are described on this Unix.SE question.

. path/to/script
source path/to/script

Finally you mentioned sh script. Again, this only works for shell scripts and not binaries. You are basically executing the sh program with the script name as argument. In the case of sh, it just treats this argument as shell script and executes it.

For answers restricted to shellscripts, see Different ways to execute a shell script.


Thanks for all the input. I will try to answer my own question now and provide a complete guide to the different possibilities to execute scripts and binaries. Please edit and comment and we'll be able to come up with something that is complete and correct. Here's my suggestion:

At first, two points to state:

  • Linux makes a distinction between a command and a path. A command is only typed as-is on the prompt, and will execute a built-in or will cause Linux to look for a corresponding binary or a script on the $PATH.

  • For Linux to interpret something as a path, it needs to contain at least one slash (/). E.g. in ./myScript, ./ can seem pretty redundant - it's there only to make Linux interpret it as a path rather than a command.

So, the options for executing a binary or a script:

Executing a binary binary:

$ binary          # when 'binary' is on the PATH, or is a built-in
$ ./binary        # when 'binary' is not on the path but in the current directory
$ /home/me/binary # when 'binary' is not on the PATH, and not in the current dir

Executing a script script:

The file will have to have execute permissions unless stated otherwise.

$ script        # execute a script that is on PATH. Will be executed in a new shell.
                # The interpreter to use is determined by the she-bang in the file.
$ ./script      # execute a script that is in the current dir. Otherwise as above.
$ /a/dir/script # when the script is not on the PATH and not in current dir. 
                # Otherwise as above.
$ . script      # execute a script in the current dir. Will be executed in the
                # current shell environment.
$ source script # equivalent to the above *1
$ sh script     # executes 'script' in a new shell *2 (the same goes for 'bash ...',
                # 'zsh ...' etc.). Execute permission not neccessary.

About she-bangs:

Scripts with a she-bang (e.g. #!/bin/sh) on the first line tells which interpreter to use.

  • This interpreter will be used when executed by ./script or using a command: script (script must be on the PATH)
  • Using sh script will ignore the she-bang and use, in this case, sh as the interpreter
  • Using . script or source will ignore the she-bang and use the current interpreter (since . or source is equivalent to just executing each line of the script in the current shell)

Footnotes

*1: This is only almost true. In bash they are indeed the same command, but when using source, script will be searched for in $PATH before the current dir. That's bash, but in POSIX-only shells, source doesn't work, but . does. So rather use the latter for portability.

*2: what actually happens is that we run the binary sh with 'script' as argument, which will make 'sh' execute 'script' in its new shell


Here's a quick listing of commands. Note, when I mention PATH, I mean the directories containing programs that the system knows about; you find those with echo $PATH, and it will be something like: /home/mike/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Scripts

  • To execute a script in current working directory, use ./myscript.sh
  • To execute a script on another file, use (if it is in the current working directory), ./myscript.sh textfile.txt
  • Scripts can also be run with arguments; as explained in Rute (p. 68): myfile.sh dogs cats birds will output The first argument is: dogs, second argument is: cats, third argument is: birds because the content of this script after the shebang is: echo "The first argument is: $1, second argument is: $2, third argument is: $3"

  • To execute a script in another directory, use ~/Scripts/dogs.sh

  • To execute a script that the system knows about because it is in your bin folder in your home directory (just create it if it isn't there, as it will automatically be added to your PATH), just use scriptname
  • To execute a script you have installed, again just use its name, because it will be known to the system: for example, get_iplayer

Binaries

  • To run a binary that the system knows about because it is in $PATH, use the name of the program and any parameters, for example, vlc <stream url to open>
  • To test a binary you have compiled before installing to /usr/local/bin, or to keep a standalone program away from the system, use ~/<folder>/app/myprog