Up Next Previous

Builtin and non-builtin command execution

Builtin commands are executed within the shell. If any component of a pipeline except the last is a builtin command, the pipeline is executed in a subshell.

Parenthesized commands are always executed in a subshell.

(cd; pwd); pwd

thus prints the home directory, leaving you where you were (printing this after the home directory), while

cd; pwd

leaves you in the home directory. Parenthesized commands are most often used to prevent cd from affecting the current shell.

When a command to be executed is found not to be a builtin command the shell attempts to execute the command via execve(2). Each word in the variable path names a directory in which the shell will look for the command. If the shell is not given a -f option, the shell hashes the names in these directories into an internal table so that it will try an execve(2) in only a directory where there is a possibility that the command resides there. This greatly speeds command location when a large number of directories are present in the search path. This hashing mechanism is not used:

1.
If hashing is turned explicitly off via unhash.

2.
If the shell was given a -f argument.

3.
For each directory component of path which does not begin with a `/'.

4.
If the command contains a `/'.

In the above four cases the shell concatenates each component of the path vector with the given command name to form a path name of a file which it then attempts to execute it. If execution is successful, the search stops.

If the file has execute permissions but is not an executable to the system (i.e., it is neither an executable binary nor a script that specifies its interpreter), then it is assumed to be a file containing shell commands and a new shell is spawned to read it. The shell special alias may be set to specify an interpreter other than the shell itself.

On systems which do not understand the `#!' script interpreter convention the shell may be compiled to emulate it; see the version shell variable. If so, the shell checks the first line of the file to see if it is of the form `#!interpreter arg ...'. If it is, the shell starts interpreter with the given args and feeds the file to it on standard input.

Up Next Previous