|
|
When the shell has processed a command line and is left with a name that is not a built-in command, the name of a function, or a second or subsequent command in a pipeline, it checks the directories listed in your PATH environment variable for a file that matches that name and on which the executable permission is set for users in your category.
If such a file exists and is an executable binary file (that is, a program that has been compiled into machine code), the shell forks; that is, it creates a copy of itself (a ``child'' process) in the computer's memory (see fork(S) for a list of the characteristics inherited by a child process from its parent).
The child process then execs the binary file; that is, it loads a copy of the binary file's instructions in place of its own, and begins to execute it. When a shell process execs another process, the new process completely replaces the shell process in the computer's memory. The parent shell remains in memory, and waits until the child process terminates before it resumes operation.
If the file that the shell finds is not a binary file, a different course of events occurs. The shell forks a child shell that automatically opens the file and begins to interpret it, one line at a time, as if each line is being typed on the shell's standard input. This is why such a text file is called a shell script; it is literally a script of actions to be carried out by the subshell.
Note that the output of a script that runs in a subshell is not automatically available to the parent shell; while the subshell ``inherits'' (that is, receives a copy of) the environment of its parent, the parent does not experience any changes that the subshell makes to its environment. So if you use a script to set a variable, the variable will not be present in the parent shell's environment.
You can work around this by using the dot (.) command. If
you have a script called myprog, then you can execute it
as follows:
. myprog
The script will be opened and interpreted directly by the current shell, without forking a sub-shell. Therefore, a script executed by the dot command can change your environment; a script executed by typing its name cannot.
For example, suppose you have a script called setvars, which contains the following:
PATH=/bin:/usr/bin:/usr/local/bin:$HOME/bin:You can use it to change your path only if you execute it with the dot command. For example:
$echo $PATH
/bin:/usr/bin:/usr/local/bin $setvars
$echo $PATH
/bin:/usr/bin:/usr/local/bin $. setvars
$echo $PATH
:/bin:/usr/bin:/usr/local/bin:$HOME/bin: $