Different ways of executing binaries and scripts

55,398

Solution 1

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.

Solution 2

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

Solution 3

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
Share:
55,398

Related videos on Youtube

Carl
Author by

Carl

Updated on September 18, 2022

Comments

  • Carl
    Carl over 1 year

    I've been using Linux for some time now and I've been searching for a complete overview of this but not found any.

    I just don't come to terms with all the different ways of executing scripts and binaries - it's all a big mess for me and I have to use trial-and-error to determine what I should use. For a file which is a script or a binary <script/binary>, I can come up with the following alternatives:

    <script/binary>
    . <script/binary>
    ./<script/binary>
    source <script/binary>
    sh <script/binary>
    

    (Are there more?)

    Can someone give a complete overview of what commands work with which kinds of files, and what the difference is when there are multiple options?

    Thanks.

  • Carl
    Carl almost 12 years
    Thanks for info. Is this statement correct: To execute a script or binary not in PATH one simply specifies its path. The reason ./ is needed for a script in the current path is that just 'script.sh' would be interpreted as a command since it lacks at least one slash /.
  • Carl
    Carl almost 12 years
    "To execute a script you have installed", what is a script that I "have installed"? Does this point say the same than the previous point?
  • Admin
    Admin almost 12 years
    @Carl- your first comment is correct, but it is not true to say that my last two points about scripts are the same. In point 5 of the script section I was talking about scripts that the user has manually added to their bin folder in their home directory; in point 6 I was talking about scripts such as get_iplayer that they have installed from the repositories and as such always go into system folders, not into the user's home directory.
  • Carl
    Carl almost 12 years
    Sorry but I still don't understand that, a script in ~/bin/ (which is in PATH) or in a system folder (which is in PATH) - how can there be a difference between them? Do they behave differently?
  • Admin
    Admin almost 12 years
    I was just making a distinction between those scripts that the user owns and adds to in ~/bin and those that are owned by root in the system folders.
  • Rustam A.
    Rustam A. almost 3 years
    Nice question, but it seems for me you have a few misinterprets in your answer. They are: 1) ./ - is there for a security issue: stackoverflow.com/questions/18552241/…; 2) $ . script # execute a script in the current dir. - it does not - it looks for a Command named script. To execute script in cur dir you should do $ . ./script or $ source ./script