|< Day Day Up >|
1.6. The Environment and Inheritance
When you log on, the shell starts up and inherits a number of
1.6.1 Ownership and Permissions
When you log on, the shell is given an identity. It has a real user identification (UID), one or more real
The real UID is the third entry in the
file. Its value is a positive integer that is associated with your login
You can use the id command to see these values, as shown in Example 1.6.
1 $ id uid=502(ellie) gid=502(ellie)
The EUID and EGID can be changed to numbers assigned to a different owner. By changing the EUID (or EGID) to another owner, you can become the owner of a process that belongs to someone else. Programs that change the EUID or EGID to another owner are called setuid or setgid programs. The passwd program is an example of a setuid program that gives the user root privileges. This enables an ordinary user to change his password, and update the passwd file (accessible only to root) without calling for a system administrator. The user temporarily becomes the superuser, root , as long as the passwd program is running because his effective user ID is temporarily is set to root . Setuid programs are often sources for security holes. The shell allows you to create setuid scripts, and the shell itself may be a setuid program. (See Chapter 16, "The System Administrator and the Shell."
1.6.2 The File Creation Mask
When a file is created it is given a set of default permissions. These permissions are determined by the program creating the file. Child processes inherit a default mask from their parents. The user can change the mask for the shell by issuing the umask command at the prompt or by setting it in the shell's initialization files. The umask command is used to remove permissions from the existing mask.
Initially, the umask is 000, giving a directory 777 ( rwxrwxrwx ) permissions and a file 666 ( rw-rw-rw- ) permissions as the default. On most systems, the umask is assigned a value of 022 by the /bin/login program or the /etc/profile initialization file.
value is subtracted from the default settings for both the directory and file permissions as
777 (Directory) 666 (File) 022 (umask value) 022 (umask value) ------- --------- 755 644 Result: drwxr-xr-x -rw-r--r--
After the umask is set, all directories and files created by this process are assigned the new default permissions. In this example, directories will be given read, write, and execute for the owner; read and execute for the group; and read and execute for the rest of the world (others). Any files created will be assigned read and write for the owner, and read for the group and others. To change permissions on individual directories and permissions, the chmod command is used.
1.6.3 Changing Permissions and Ownership
The chmod Command
command changes permissions on files and directories. Every UNIX/Linux file has a set of permissions associated with it to control who can read, write, or execute the file. There is one owner for every UNIX/Linux file and only the owner or the superuser can change the permissions on a file or directory. A group may have a number of
ls -l filename
A total of nine bits
Table 1.1 illustrates the eight possible combinations of numbers used for changing permissions.
Table 1.1. Permission Modes
1 $ chmod 755 file $ ls l file rwxrxrx 1 ellie 0 Mar 7 12:52 file 2 $ chmod g+w file $ ls -l file rwxrwxr-x 1 ellie 0 Mar 7 12:54 file 3 $ chmod go-rx file $ ls -l file rwx-w---- 1 ellie 0 Mar 7 12:56 file 4 $ chmod a=r file $ ls -l file r--r--r-- 1 ellie 0 Mar 7 12:59 file
The chown Command
command changes the owner and group on files and directories. If using Linux, only the superuser,
, can change ownership. If using UNIX, the owner of the file or the superuser can change the ownership. To see the usage and options for
, check the man pages (UNIX) or use the
command with the
(Linux) option as shown in Example 1.8. Example 1.9
(The Command Line) # chown --help Usage: chown [OPTION]... OWNER[.[GROUP]] FILE... or: chown [OPTION]... .[GROUP] FILE... Change the owner and/or group of each FILE to OWNER and/or GROUP. -c, --changes be verbose whenever change occurs -h, --no-dereference affect symbolic links instead of any referenced file (available only on systems with lchown system call) -f, --silent, --quiet suppress most error messages -R, --recursive operate on files and directories recursively -v, --verbose explain what is being done --help display this help and exit --version output version information and exit Owner is unchanged if missing. Group is unchanged if missing, but changed to login group if implied by a period. A colon may replace the period. Report bugs to email@example.com
(The Command Line) 1 $ ls -l filetest -rw-rw-r-- 1 ellie ellie 0 Jan 10 12:19 filetest 2 $ chown root filetest chown: filetest: Operation not permitted 3 $ su root Password: 4 # ls -l filetest - rw-rw-r-- 1 ellie ellie 0 Jan 10 12:19 filetest 5 # chown root filetest 6 # ls -l filetest -rw-rw-r-- 1 root ellie 0 Jan 10 12:19 filetest 7 # chown root:root filetest 8 # ls -l filetest -rw-rw-r-- 1 root root 0 Jan 10 12:19 filetest
1.6.4 The Working Directory
When you log on, you are given a working directory within the file system, called the home directory . The working directory is inherited by processes spawned from this shell. Any child process of this shell can change its own working directory, but the change will have no effect on the parent shell.
command, used to change the working directory, is a shell built-in command. Each shell has its own copy of
. A built-in command is executed directly by the shell as part of the shell's code; the shell does not perform the
1 > cd / 2 > pwd / 3 > bash 4 $ cd /home 5 $ pwd /home 6 $ exit 7 > pwd / >
The shell can define two types of variables: local and environment. The variables contain information used for customizing the shell, and information required by other processes so that they will function properly. Local variables are private to the shell in which they are created and not passed on to any processes spawned from that shell. The built-in
command will display local variables for C shell and TC shell, and both local and environment variables for Bourne, Bash, and Korn
$ env PWD=/home/ellie TZ=US/Pacific PAGER=less HOSTNAME=artemis LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/dt/lib:/usr/openwin/lib MANPATH=/usr/local/man:/usr/man:/usr/openwin/man:/opt/httpd/man USER=ellie MACHTYPE=sparcsunsolaris2.9 TCL_LIBRARY=/usr/local/lib/tcl8.0 EDITOR=vi LOGNAME=ellie SHLVL=1 SHELL=/bin/bash HOSTTYPE=sparc OSTYPE=solaris2.9 HOME=/home/ellie TERM=xterm TK_LIBRARY=/usr/local/lib/tk8.0 PATH=/bin:/usr/bin:/usr/local/bin:/usr/local/etc:/usr/ccs/bin:/usr/etc:/usr/ucb:/usr/ local/X11:/usr/openwin/bin:/etc:. SSH_TTY=/dev/pts/10 _=/bin/env
1.6.6 Redirection and Pipes
All I/O, including files, pipes, and sockets, is handled by the kernel via a mechanism called the
. A file descriptor is a small unsigned integer, an index into a file-descriptor table
When a file descriptor is assigned to something other than a terminal, it is called
. The shell
1 $ who > file 2 $ cat file1 file2 >> file3 3 $ mail tom < file 4 $ find / -name file -print 2> errors 5 % (find / -name file -print > /dev/tty) >& errors
Figure 1.5. Redirection of standard output.
Figure 1.6. Redirection of standard input.
Figure 1.7. Redirection of standard error (Bourne, Bash, and Korn shells).
Figure 1.8. Redirection of standard error (C and TC shells).
A pipe is the oldest form of UNIX interprocess communication. A pipe allows processes to communicate with each other. It is a mechanism whereby the output of one command is sent as input to another command, with the limitation that data can only flow in one direction, normally between a parent and a child. The shell implements pipes by closing and opening file descriptors; however, instead of assigning the descriptors to a file, it assigns them to a pipe descriptor created with the pipe system call. After the parent creates the pipe file descriptors, it forks a child process for each command in the pipeline. By having each process manipulate the pipe descriptors, one will write to the pipe and the other will read from it.
To simplify things, a pipe is merely a kernel buffer from which both processes can share data, thus eliminating the need for intermediate temporary files. The output of one command is sent to the buffer, and when the buffer is full or the command has
The syntax of the pipe command is
In order to accomplish the same thing without a pipe, it would take three steps:
who > tempfile wc tempfile rm tempfile
With the pipe, the shell sends the output of the
command as input to the
command; that is, the command on the left-hand side of the pipe
to the pipe and the command on the right-hand side of the pipe
from it (see Figure 1.9). You can tell if a command is a writer if it normally sends output to the screen when run at the command line. The
commands are examples of writers. A reader is a command that waits for input from a file or from the keyboard or from a pipe. The
Figure 1.9. The pipe.
Figures 1.10 through 1.14
Figure 1.10. The parent calls the pipe system call for setting up a pipeline.
Figure 1.14. The output of who is sent to the input of wc .
Figure 1.11. The parent forks two child processes, one for each command in the pipeline.
Figure 1.12. The first child is prepared to write to the pipe.
Figure 1.13. The second child is prepared to read input from the pipe.
1.6.7 The Shell and Signals
A signal sends a message to a process and normally causes the process to terminate, usually due to some unexpected event such as a hangup, bus error, or power failure, or by a program error such as illegal division by zero or an invalid memory reference. Signals can also be sent to a process by pressing certain key sequences. For example, you can send or deliver signals to a process by pressing the Break, Delete, Quit, or Stop keys, and all processes sharing the terminal are affected by the signal sent. You can kill a process with the kill command. By default, most signals terminate the program. Each process can take an action in response to a given signal:
The Bourne, Bash, and Korn shells allow you to handle signals coming into your program, (see "Trapping Signals" on page 378 for programming in the Bourne shell; "Trapping Signals" on page 716 for programming in the Korn shell; and "Trapping Signals" on page 935 for programing in the Bash shell) either by ignoring the signal, by specifying some action to be taken when a specified signal arrives, or by resetting the signal back to its default action. The C and TC shells are limited to handling ^C (Ctrl-C), the interrupt character.
Table 1.2 lists the standard signals that a process can use.
Table 1.2. Standard Signals [a]