old-www/LDP/intro-linux/html/sect_07_02.html

2026 lines
35 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>Your text environment</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Introduction to Linux"
HREF="index.html"><LINK
REL="UP"
TITLE="Home sweet /home"
HREF="chap_07.html"><LINK
REL="PREVIOUS"
TITLE="General good housekeeping"
HREF="sect_07_01.html"><LINK
REL="NEXT"
TITLE="The graphical environment"
HREF="sect_07_03.html"></HEAD
><BODY
CLASS="sect1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Introduction to Linux: </TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="sect_07_01.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 7. Home sweet /home</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="sect_07_03.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="sect1"
><H1
CLASS="sect1"
><A
NAME="sect_07_02"
></A
>7.2. Your text environment</H1
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_07_02_1"
></A
>7.2.1. Environment variables</H2
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_01"
></A
>7.2.1.1. General</H3
><P
>We already mentioned a couple of environment variables, such as <TT
CLASS="varname"
>PATH</TT
> and <TT
CLASS="varname"
>HOME</TT
>. Until now, we only saw examples in which they serve a certain purpose to the shell. But there are many other Linux utilities that need information about you in order to do a good job.</P
><P
>What other information do programs need apart from paths and home directories?</P
><P
>A lot of programs want to know about the kind of terminal you are using; this information is stored in the <TT
CLASS="varname"
>TERM</TT
> variable. In text mode, this will be the <EM
>linux</EM
> terminal emulation, in graphical mode you are likely to use <EM
>xterm</EM
>. Lots of programs want to know what your favorite editor is, in case they have to start an editor in a subprocess. The shell you are using is stored in the <TT
CLASS="varname"
>SHELL</TT
> variable, the operating system type in <TT
CLASS="varname"
>OS</TT
> and so on. A list of all variables currently defined for your session can be viewed entering the <B
CLASS="command"
>printenv</B
> command.</P
><P
>The environment variables are managed by the shell. As opposed to regular shell variables, environment variables are inherited by any program you start, including another shell. New processes are assigned a copy of these variables, which they can read, modify and pass on in turn to their own child processes.</P
><P
>There is nothing special about variable names, except that the common ones are in upper case characters by convention. You may come up with any name you want, although there are standard variables that are important enough to be the same on every Linux system, such as <TT
CLASS="varname"
>PATH</TT
> and <TT
CLASS="varname"
>HOME</TT
>.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_02"
></A
>7.2.1.2. Exporting variables</H3
><P
>An individual variable's content is usually displayed using the <B
CLASS="command"
>echo</B
> command, as in these examples:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>echo $PATH</B
>
/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin:/usr/local/bin
<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>echo $MANPATH</B
>
/usr/man:/usr/share/man/:/usr/local/man:/usr/X11R6/man
</PRE
></FONT
></TD
></TR
></TABLE
><P
>If you want to change the content of a variable in a way that is useful to other programs, you have to export the new value from your environment into the environment that runs these programs. A common example is exporting the <TT
CLASS="varname"
>PATH</TT
> variable. You may declare it as follows, in order to be able to play with the flight simulator software that is in <TT
CLASS="filename"
>/opt/FlightGear/bin</TT
>:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>PATH=$PATH:/opt/FlightGear/bin</B
>
</PRE
></FONT
></TD
></TR
></TABLE
><P
>This instructs the shell to not only search programs in the current path, <TT
CLASS="varname"
>$PATH</TT
>, but also in the additional directory <TT
CLASS="filename"
>/opt/FlightGear/bin</TT
>.</P
><P
>However, as long as the new value of the <TT
CLASS="varname"
>PATH</TT
> variable is not known to the environment, things will still not work:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>runfgfs</B
>
bash: runfgfs: command not found
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Exporting variables is done using the shell built-in command <B
CLASS="command"
>export</B
>:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>export PATH</B
>
<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>runfgfs</B
>
--flight simulator starts--
</PRE
></FONT
></TD
></TR
></TABLE
><P
>In <SPAN
CLASS="application"
>Bash</SPAN
>, we normally do this in one elegant step:</P
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>VARIABLE</TT
>=<TT
CLASS="replaceable"
><I
>value</I
></TT
></B
> </P
><P
>The same technique is used for the <TT
CLASS="varname"
>MANPATH</TT
> variable, that tells the <B
CLASS="command"
>man</B
> command where to look for compressed man pages. If new software is added to the system in new or unusual directories, the documentation for it will probably also be in an unusual directory. If you want to read the man pages for the new software, extend the <TT
CLASS="varname"
>MANPATH</TT
> variable:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>export MANPATH=$MANPATH:/opt/FlightGear/man</B
>
<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>echo $MANPATH</B
>
/usr/man:/usr/share/man:/usr/local/man:/usr/X11R6/man:/opt/FlightGear/man
</PRE
></FONT
></TD
></TR
></TABLE
><P
>You can avoid retyping this command in every window you open by adding it to one of your shell setup files, see <A
HREF="sect_07_02.html#sect_07_02_04"
>Section 7.2.2</A
>.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_03"
></A
>7.2.1.3. Reserved variables</H3
><P
>The following table gives an overview of the most common predefined variables:</P
><DIV
CLASS="table"
><A
NAME="AEN7272"
></A
><P
><B
>Table 7-1. Common environment variables</B
></P
><TABLE
BORDER="1"
CLASS="CALSTABLE"
><THEAD
><TR
><TH
ALIGN="LEFT"
VALIGN="MIDDLE"
>Variable name</TH
><TH
ALIGN="LEFT"
VALIGN="MIDDLE"
>Stored information</TH
></TR
></THEAD
><TBODY
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>DISPLAY</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>used by the X Window system to identify the display server</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>DOMAIN</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>domain name</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>EDITOR</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>stores your favorite line editor</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>HISTSIZE</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>size of the shell history file in number of lines</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>HOME</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>path to your home directory</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>HOSTNAME</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>local host name</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>INPUTRC</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>location of definition file for input devices such as keyboard</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>LANG</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>preferred language</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>LD_LIBRARY_PATH</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>paths to search for libraries</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>LOGNAME</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>login name</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>MAIL</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>location of your incoming mail folder</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>MANPATH</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>paths to search for man pages</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>OS</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>string describing the operating system</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>OSTYPE</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>more information about version etc.</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>PAGER</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>used by programs like <B
CLASS="command"
>man</B
> which need to know what to do in case output is more than one terminal window.</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>PATH</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>search paths for commands</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>PS1</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>primary prompt</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>PS2</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>secondary prompt</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>PWD</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>present working directory</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>SHELL</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>current shell</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>TERM</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>terminal type</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>UID</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>user ID</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>USER(NAME)</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>user name</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>VISUAL</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>your favorite full-screen editor</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>XENVIRONMENT</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>location of your personal settings for X behavior</TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
><TT
CLASS="varname"
>XFILESEARCHPATH</TT
></TD
><TD
ALIGN="LEFT"
VALIGN="MIDDLE"
>paths to search for graphical libraries</TD
></TR
></TBODY
></TABLE
></DIV
><P
>A lot of variables are not only predefined but also preset, using configuration files. We discuss these in the next section.</P
></DIV
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_07_02_04"
></A
>7.2.2. Shell setup files</H2
><P
>When entering the <B
CLASS="command"
>ls <TT
CLASS="option"
>-al</TT
></B
> command to get a long listing of all files, including the ones starting with a dot, in your home directory, you will see one or more files starting with a . and ending in <EM
>rc</EM
>. For the case of <B
CLASS="command"
>bash</B
>, this is <TT
CLASS="filename"
>.bashrc</TT
>. This is the counterpart of the system-wide configuration file <TT
CLASS="filename"
>/etc/bashrc</TT
>.</P
><P
>When logging into an interactive login shell, <B
CLASS="command"
>login</B
> will do the authentication, set the environment and start your shell. In the case of <B
CLASS="command"
>bash</B
>, the next step is reading the general <TT
CLASS="filename"
>profile</TT
> from <TT
CLASS="filename"
>/etc</TT
>, if that file exists. <B
CLASS="command"
>bash</B
> then looks for <TT
CLASS="filename"
>~/.bash_profile</TT
>, <TT
CLASS="filename"
>~/.bash_login</TT
> and <TT
CLASS="filename"
>~/.profile</TT
>, in that order, and reads and executes commands from the first one that exists and is readable. If none exists, <TT
CLASS="filename"
>/etc/bashrc</TT
> is applied.</P
><P
>When a login shell exits, <B
CLASS="command"
>bash</B
> reads and executes commands from the file <TT
CLASS="filename"
>~/.bash_logout</TT
>, if it exists.
</P
><P
>This procedure is explained in detail in the <B
CLASS="command"
>login</B
> and <B
CLASS="command"
>bash</B
> man pages.</P
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_07_02_05"
></A
>7.2.3. A typical set of setup files</H2
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_05_01"
></A
>7.2.3.1. /etc/profile example</H3
><P
>Let's look at some of these config files. First <TT
CLASS="filename"
>/etc/profile</TT
> is read, in which important variables such as <TT
CLASS="varname"
>PATH</TT
>, <TT
CLASS="varname"
>USER</TT
> and <TT
CLASS="varname"
>HOSTNAME</TT
> are set:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>cat /etc/profile</B
>
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
# Path manipulation
if [ `id -u` = 0 ] &#38;&#38; ! echo $PATH | /bin/grep -q "/sbin" ; then
PATH=/sbin:$PATH
fi
if [ `id -u` = 0 ] &#38;&#38; ! echo $PATH | /bin/grep -q "/usr/sbin" ; then
PATH=/usr/sbin:$PATH
fi
if [ `id -u` = 0 ] &#38;&#38; ! echo $PATH | /bin/grep -q "/usr/local/sbin"
then
PATH=/usr/local/sbin:$PATH
fi
if ! echo $PATH | /bin/grep -q "/usr/X11R6/bin" ; then
PATH="$PATH:/usr/X11R6/bin"
fi
</PRE
></FONT
></TD
></TR
></TABLE
><P
>These lines check the path to set: if <EM
>root</EM
> opens a shell (user ID 0), it is checked that <TT
CLASS="filename"
>/sbin</TT
>, <TT
CLASS="filename"
>/usr/sbin</TT
> and <TT
CLASS="filename"
>/usr/local/sbin</TT
> are in the path. If not, they are added. It is checked for everyone that <TT
CLASS="filename"
>/usr/X11R6/bin</TT
> is in the path.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;# No core files by default
ulimit -S -c 0 &#62; /dev/null 2&#62;&#38;1
</PRE
></FONT
></TD
></TR
></TABLE
><P
>All trash goes to <TT
CLASS="filename"
>/dev/null</TT
> if the user doesn't change this setting.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;USER=`id -un`
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
HOSTNAME=`/bin/hostname`
HISTSIZE=1000
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Here general variables are assigned their proper values.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
INPUTRC=/etc/inputrc
fi
</PRE
></FONT
></TD
></TR
></TABLE
><P
>If the variable <TT
CLASS="varname"
>INPUTRC</TT
> is not set, and there is no <TT
CLASS="filename"
>.inputrc</TT
> in the user's home directory, then the default input control file is loaded. </P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
</PRE
></FONT
></TD
></TR
></TABLE
><P
>All variables are exported, so that they are available to other programs requesting information about your environment.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_05_02"
></A
>7.2.3.2. The profile.d directory</H3
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;for i in /etc/profile.d/*.sh ; do
if [ -r $i ]; then
. $i
fi
done
unset i
</PRE
></FONT
></TD
></TR
></TABLE
><P
>All readable shell scripts from the <TT
CLASS="filename"
>/etc/profile.d</TT
> directory are read and executed. These do things like enabling <EM
>color-ls</EM
>, aliasing <B
CLASS="command"
>vi</B
> to <B
CLASS="command"
>vim</B
>, setting locales etc. The temporary variable <TT
CLASS="varname"
>i</TT
> is unset to prevent it from disturbing shell behavior later on.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_05_03"
></A
>7.2.3.3. .bash_profile example</H3
><P
>Then <B
CLASS="command"
>bash</B
> looks for a <TT
CLASS="filename"
>.bash_profile</TT
> in the user's home directory:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>cat .bash_profile </B
>
#################################################################
# #
# .bash_profile file #
# #
# Executed from the bash shell when you log in. #
# #
#################################################################
source ~/.bashrc
source ~/.bash_login
</PRE
></FONT
></TD
></TR
></TABLE
><P
>This very straight forward file instructs your shell to first read <TT
CLASS="filename"
>~/.bashrc</TT
> and then <TT
CLASS="filename"
>~/.bash_login</TT
>. You will encounter the <B
CLASS="command"
>source</B
> built-in shell command regularly when working in a shell environment: it is used to apply configuration changes to the current environment.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_05_04"
></A
>7.2.3.4. .bash_login example</H3
><P
>The <TT
CLASS="filename"
>~/.bash_login</TT
> file defines default file protection by setting the <B
CLASS="command"
>umask</B
> value, see <A
HREF="sect_03_04.html#sect_03_04_02_02"
>Section 3.4.2.2</A
>. The <TT
CLASS="filename"
>~/.bashrc</TT
> file is used to define a bunch of user-specific aliases and functions and personal environment variables. It first reads <TT
CLASS="filename"
>/etc/bashrc</TT
>, which describes the default prompt (<TT
CLASS="varname"
>PS1</TT
>) and the default umask value. After that, you can add your own settings. If no <TT
CLASS="filename"
>~/.bashrc</TT
> exists, <TT
CLASS="filename"
>/etc/bashrc</TT
> is read by default.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_05_05"
></A
>7.2.3.5. /etc/bashrc example</H3
><P
>Your <TT
CLASS="filename"
>/etc/bashrc</TT
> file might look like this:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>cat /etc/bashrc</B
>
# /etc/bashrc
# System wide functions and aliases
# Environment stuff goes in /etc/profile
# by default, we want this to get set.
# Even for non-interactive, non-login shells.
if [ `id -gn` = `id -un` -a `id -u` -gt 99 ]; then
umask 002
else
umask 022
fi
</PRE
></FONT
></TD
></TR
></TABLE
><P
>These lines set the <B
CLASS="command"
>umask</B
> value. Then, depending on the type of shell, the prompt is set:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;# are we an interactive shell?
if [ "$PS1" ]; then
if [ -x /usr/bin/tput ]; then
if [ "x`tput kbs`" != "x" ]; then
# We can't do this with "dumb" terminal
stty erase `tput kbs`
elif [ -x /usr/bin/wc ]; then
if [ "`tput kbs|wc -c `" -gt 0 ]; then
# We can't do this with "dumb" terminal
stty erase `tput kbs`
fi
fi
fi
case $TERM in
xterm*)
if [ -e /etc/sysconfig/bash-prompt-xterm ]; then
PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
else
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:\
${PWD/$HOME/~}\007"'
fi
;;
*)
[ -e /etc/sysconfig/bash-prompt-default ] &#38;&#38; PROMPT_COMMAND=\
/etc/sysconfig/bash-prompt-default
;;
esac
[ "$PS1" = "\\s-\\v\\\$ " ] &#38;&#38; PS1="[\u@\h \W]\\$ "
if [ "x$SHLVL" != "x1" ]; then # We're not a login shell
for i in /etc/profile.d/*.sh; do
if [ -x $i ]; then
. $i
fi
done
fi
fi
</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_05_06"
></A
>7.2.3.6. .bash_logout example</H3
><P
>Upon logout, the commands in <TT
CLASS="filename"
>~/.bash_logout</TT
> are executed, which can for instance clear the terminal, so that you have a clean window upon logging out of a remote session, or upon leaving the system console:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>debby:~&#62;</TT
> <B
CLASS="command"
>cat .bash_logout</B
>
# ~/.bash_logout
clear
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Let's take a closer look at how these scripts work in the next section. Keep <B
CLASS="command"
>info <TT
CLASS="parameter"
><I
>bash</I
></TT
></B
> close at hand.</P
></DIV
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_07_02_06"
></A
>7.2.4. The Bash prompt</H2
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_06_01"
></A
>7.2.4.1. Introduction</H3
><P
>&#13;The <SPAN
CLASS="application"
>Bash</SPAN
> prompt can do much more than displaying such simple information as your user name, the name of your machine and some indication about the present working directory. We can add other information such as the current date and time, number of connected users etc.</P
><P
>Before we begin, however, we will save our current prompt in another environment variable:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>[jerry@nowhere jerry]$</TT
> <B
CLASS="command"
>MYPROMPT=$PS1</B
>
<TT
CLASS="prompt"
>[jerry@nowhere jerry]$</TT
> <B
CLASS="command"
>echo $MYPROMPT</B
>
[\u@\h \W]\$
<TT
CLASS="prompt"
>[jerry@nowhere jerry]$</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
><P
>When we change the prompt now, for example by issuing the command <B
CLASS="command"
><TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"-&#62;"</I
></TT
></B
>, we can always get our original prompt back with the command <B
CLASS="command"
><TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="varname"
>$MYPROMPT</TT
></B
>. You will, of course, also get it back when you reconnect, as long as you just fiddle with the prompt on the command line and avoid putting it in a shell configuration file.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_06_02"
></A
>7.2.4.2. Some examples</H3
><P
>In order to understand these prompts and the escape sequences used, we refer to the <SPAN
CLASS="application"
>Bash Info</SPAN
> or man pages.</P
><P
></P
><UL
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"[\t \j] "</I
></TT
></B
></P
><P
>Displays time of day and number of running jobs</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"[\d][\u@\h \w] : "</I
></TT
></B
></P
><P
>Displays date, user name, host name and current working directory. Note that \W displays only base names of the present working directory.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"{\!} "</I
></TT
></B
></P
><P
>Displays history number for each command.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"\[\033[1;35m\]\u@\h\[\033[0m\] "</I
></TT
></B
></P
><P
>Displays user@host in pink.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"\[\033[1;35m\]\u\[\033[0m\] \[\033[1;34m\]\w\[\033[0m\] "</I
></TT
></B
></P
><P
>Sets the user name in pink and the present working directory in blue.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"\[\033[1;44m\]$USER is in \w\[\033[0m\] "</I
></TT
></B
></P
><P
>Prompt for people who have difficulties seeing the difference between the prompt and what they type.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"\[\033[4;34m\]\u@\h \w \[\033[0m\]"</I
></TT
></B
></P
><P
>Underlined prompt.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"\[\033[7;34m\]\u@\h \w \[\033[0m\] "</I
></TT
></B
></P
><P
>White characters on a blue background.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=<TT
CLASS="replaceable"
><I
>"\[\033[3;35m\]\u@\h \w \[\033[0m\]\a"</I
></TT
></B
></P
><P
>Pink prompt in a lighter font that alerts you when your commands have finished.</P
></LI
><LI
><P
><B
CLASS="command"
>export <TT
CLASS="varname"
>PS1</TT
>=...</B
></P
></LI
></UL
><P
>Variables are exported so the subsequently executed commands will also know about the environment. The prompt configuration line that you want is best put in your shell configuration file, <TT
CLASS="filename"
>~/.bashrc</TT
>.</P
><P
>If you want, prompts can execute shell scripts and behave different under different conditions. You can even have the prompt play a tune every time you issue a command, although this gets boring pretty soon. More information can be found in the <A
HREF="http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/"
TARGET="_top"
>Bash-Prompt HOWTO</A
>.</P
></DIV
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_07_02_07"
></A
>7.2.5. Shell scripts</H2
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_07_01"
></A
>7.2.5.1. What are scripts?</H3
><P
>A shell script is, as we saw in the shell configuration examples, a text file containing shell commands. When such a file is used as the first non-option argument when invoking <SPAN
CLASS="application"
>Bash</SPAN
>, and neither the <TT
CLASS="option"
>-c</TT
> nor <TT
CLASS="option"
>-s</TT
> option is supplied, <SPAN
CLASS="application"
>Bash</SPAN
> reads and executes commands from the file, then exits. This mode of operation creates a non-interactive shell. When <SPAN
CLASS="application"
>Bash</SPAN
> runs a shell script, it sets the special parameter <TT
CLASS="varname"
>0</TT
> to the name of the file, rather than the name of the shell, and the positional parameters (everything following the name of the script) are set to the remaining arguments, if any are given. If no additional arguments are supplied, the positional parameters are unset.</P
><P
>A shell script may be made executable by using the <B
CLASS="command"
>chmod</B
> command to turn on the execute bit. When <SPAN
CLASS="application"
>Bash</SPAN
> finds such a file while searching the <TT
CLASS="varname"
>PATH</TT
> for a command, it spawns a sub-shell to execute it. In other words, executing</P
><P
><B
CLASS="command"
>filename <TT
CLASS="parameter"
><I
>ARGUMENTS</I
></TT
></B
> </P
><P
>is equivalent to executing</P
><P
><B
CLASS="command"
>bash <TT
CLASS="parameter"
><I
>filename</I
></TT
> <TT
CLASS="parameter"
><I
>ARGUMENTS</I
></TT
></B
> </P
><P
>if <SPAN
CLASS="QUOTE"
>"filename"</SPAN
> is an executable shell script. This sub-shell reinitializes itself, so that the effect is as if a new shell had been invoked to interpret the script, with the exception that the locations of commands remembered by the parent (see <B
CLASS="command"
>hash</B
> in the <SPAN
CLASS="application"
>Info</SPAN
> pages) are retained by the child.</P
><P
>Most versions of UNIX make this a part of the operating system's command execution mechanism. If the first line of a script begins with the two characters <SPAN
CLASS="QUOTE"
>"#!"</SPAN
>, the remainder of the line specifies an interpreter for the program. Thus, you can specify <B
CLASS="command"
>bash</B
>, <B
CLASS="command"
>awk</B
>, <B
CLASS="command"
>perl</B
> or some other interpreter or shell and write the rest of the script file in that language.</P
><P
>The arguments to the interpreter consist of a single optional argument following the interpreter name on the first line of the script file, followed by the name of the script file, followed by the rest of the arguments. <SPAN
CLASS="application"
>Bash</SPAN
> will perform this action on operating systems that do not handle it themselves.</P
><P
><SPAN
CLASS="application"
>Bash</SPAN
> scripts often begin with</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;#! /bin/bash
</PRE
></FONT
></TD
></TR
></TABLE
><P
>(assuming that <SPAN
CLASS="application"
>Bash</SPAN
> has been installed in <TT
CLASS="filename"
>/bin</TT
>), since this ensures that <SPAN
CLASS="application"
>Bash</SPAN
> will be used to interpret the script, even if it is executed under another shell.</P
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_07_02_07_02"
></A
>7.2.5.2. Some simple examples</H3
><P
>A very simple script consisting of only one command, that says hello to the user executing it:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>[jerry@nowhere ~]</TT
> <B
CLASS="command"
>cat hello.sh</B
>
#!/bin/bash
echo "Hello $USER"
</PRE
></FONT
></TD
></TR
></TABLE
><P
>The script actually consists of only one command, <B
CLASS="command"
>echo</B
>, which uses the <EM
>value of</EM
> ($) the <TT
CLASS="varname"
>USER</TT
> environment variable to print a string customized to the user issuing the command.</P
><P
>Another one-liner, used for displaying connected users:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;#!/bin/bash
who | cut -d " " -f 1 | sort -u
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Here is a script consisting of some more lines, that I use to make backup copies of all files in a directory.
The script first makes a list of all the files in the current directory and puts it in the variable <TT
CLASS="varname"
>LIST</TT
>. Then it sets the name of the copy for each file, and then it copies the file. For each file, a message is printed:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>tille:~&#62;</TT
> <B
CLASS="command"
>cat <TT
CLASS="filename"
>bin/makebackupfiles.sh</TT
></B
>
#!/bin/bash
# make copies of all files in a directory
LIST=`ls`
for i in $LIST; do
ORIG=$i
DEST=$i.old
cp $ORIG $DEST
echo "copied $i"
done
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Just entering a line like <B
CLASS="command"
>mv <TT
CLASS="parameter"
><I
>*</I
></TT
> <TT
CLASS="parameter"
><I
>*.old</I
></TT
></B
> won't work, as you will notice when trying this on a set of test files. An <B
CLASS="command"
>echo</B
> command was added in order to display some activity. <B
CLASS="command"
>echo</B
>'s are generally useful when a script won't work: insert one after each doubted step and you will find the error in no time.</P
><P
>The <TT
CLASS="filename"
>/etc/rc.d/init.d</TT
> directory contains loads of examples. Let's look at this script that controls the fictive ICanSeeYou server:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;#!/bin/sh
# description: ICanSeeYou allows you to see networked people
# process name: ICanSeeYou
# pidfile: /var/run/ICanSeeYou/ICanSeeYou.pid
# config: /etc/ICanSeeYou.cfg
# Source function library.
. /etc/rc.d/init.d/functions
# See how (with which arguments) we were called.
case "$1" in
start)
echo -n "Starting ICanSeeYou: "
daemon ICanSeeYou
echo
touch /var/lock/subsys/ICanSeeYou
;;
stop)
echo -n "Shutting down ICanSeeYou: "
killproc ICanSeeYou
echo
rm -f /var/lock/subsys/ICanSeeYou
rm -f /var/run/ICanSeeYou/ICanSeeYou.pid
;;
status)
status ICanSeeYou
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit 0
</PRE
></FONT
></TD
></TR
></TABLE
><P
>First, with the <B
CLASS="command"
>.</B
> command (dot) a set of shell functions, used by almost all shell scripts in <TT
CLASS="filename"
>/etc/rc.d/init.d</TT
>, is loaded. Then a <B
CLASS="command"
>case</B
> command is issued, which defines 4 different ways the script can execute. An example might be <B
CLASS="command"
>ICanSeeYou <TT
CLASS="parameter"
><I
>start</I
></TT
></B
>. The decision of which case to apply is made by reading the (first) argument to the script, with the expression <EM
>$1</EM
>.</P
><P
>When no compliant input is given, the default case, marked with an asterisk, is applied, upon which the script gives an error message. The <B
CLASS="command"
>case</B
> list is ended with the <B
CLASS="command"
>esac</B
> statement. In the <EM
>start</EM
> case the server program is started as a daemon, and a process ID and lock are assigned. In the <EM
>stop</EM
> case, the server process is traced down and stopped, and the lock and the PID are removed. Options, such as the <TT
CLASS="option"
>daemon</TT
> option, and functions like <TT
CLASS="option"
>killproc</TT
>, are defined in the <TT
CLASS="filename"
>/etc/rc.d/init.d/functions</TT
> file. This setup is specific to the distribution used in this example. The initscripts on your system might use other functions, defined in other files, or none at all.</P
><P
>Upon success, the script returns an exit code of zero to its parent.</P
><P
>&#13;This script is a fine example of using functions, which make the script easier to read and the work done faster. Note that they use <B
CLASS="command"
>sh</B
> instead of <B
CLASS="command"
>bash</B
>, to make them useful on a wider range of systems. On a Linux system, calling <B
CLASS="command"
>bash</B
> as <B
CLASS="command"
>sh</B
> results in the shell running in POSIX-compliant mode.</P
><P
>The <B
CLASS="command"
>bash</B
> man pages contain more information about combining commands, <B
CLASS="command"
>for</B
>- and <B
CLASS="command"
>while</B
>-loops and regular expressions, as well as examples. A comprehensible <SPAN
CLASS="application"
>Bash</SPAN
> course for system administrators and power users, with exercises, from the same author as this Introduction to Linux guide, is at <A
HREF="http://tille.garrels.be/training/bash/"
TARGET="_top"
>http://tille.garrels.be/training/bash/</A
>. Detailed description of <SPAN
CLASS="application"
>Bash</SPAN
> features and applications is in the reference guide <A
HREF="http://tldp.org/LDP/abs/html/index.html"
TARGET="_top"
>Advanced Bash Scripting</A
>.</P
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="sect_07_01.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="sect_07_03.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>General good housekeeping</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="chap_07.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The graphical environment</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>