old-www/LDP/abs/html/special-chars.html

6600 lines
88 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>Special Characters</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Advanced Bash-Scripting Guide"
HREF="index.html"><LINK
REL="UP"
TITLE="Basics"
HREF="part2.html"><LINK
REL="PREVIOUS"
TITLE="Basics"
HREF="part2.html"><LINK
REL="NEXT"
TITLE="Introduction to Variables and Parameters"
HREF="variables.html"></HEAD
><BODY
CLASS="CHAPTER"
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"
>Advanced Bash-Scripting Guide: </TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="part2.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="variables.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="SPECIAL-CHARS"
></A
>Chapter 3. Special Characters</H1
><P
>What makes a character <I
CLASS="FIRSTTERM"
>special</I
>?
If it has a meaning beyond its
<I
CLASS="FIRSTTERM"
>literal meaning</I
>, a <A
HREF="x17129.html#METAMEANINGREF"
>meta-meaning</A
>, then we refer
to it as a <I
CLASS="FIRSTTERM"
>special character</I
>. Along
with commands and <A
HREF="internal.html#KEYWORDREF"
>keywords</A
>,
<I
CLASS="FIRSTTERM"
>special characters</I
> are building blocks
of Bash scripts.</P
><P
></P
><DIV
CLASS="VARIABLELIST"
><P
><B
><A
NAME="SCHARLIST1"
></A
>Special Characters Found In
Scripts and Elsewhere</B
></P
><DL
><DT
><A
NAME="HASHMARKREF"
></A
><SPAN
CLASS="TOKEN"
>#</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Comments. </B
>Lines beginning with a <SPAN
CLASS="TOKEN"
>#</SPAN
>
(with the exception of <A
HREF="sha-bang.html#MAGNUMREF"
> <SPAN
CLASS="TOKEN"
>#!</SPAN
></A
>) are comments and will
<EM
>not</EM
> be executed.</P
></DIV
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
># This line is a comment.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>Comments may also occur following the end of a command.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo "A comment will follow." # Comment here.
# ^ Note whitespace before #</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
><A
NAME="WSBCOMM"
></A
> Comments may also follow <A
HREF="special-chars.html#WHITESPACEREF"
>whitespace</A
> at the beginning
of a line.</P
><P
> <TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
> # A tab precedes this comment.</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
><A
NAME="COMMINPIPE"
></A
>Comments may even be embedded
within a <A
HREF="special-chars.html#PIPEREF"
>pipe</A
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\
# Delete lines containing '#' comment character.
sed -e 's/\./\. /g' -e 's/_/_ /g'` )
# Excerpted from life.sh script</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/caution.gif"
HSPACE="5"
ALT="Caution"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>A command may not follow a comment on the
same line. There is no method of terminating the comment,
in order for <SPAN
CLASS="QUOTE"
>"live code"</SPAN
> to begin on the same
line. Use a new line for the next command.</P
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NOTE"
><P
></P
><TABLE
CLASS="NOTE"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>Of course, a <A
HREF="quoting.html#QUOTINGREF"
>quoted</A
>
or an <A
HREF="escapingsection.html#ESCP"
>escaped</A
> <SPAN
CLASS="TOKEN"
>#</SPAN
>
in an <A
HREF="internal.html#ECHOREF"
>echo</A
> statement does
<EM
>not</EM
> begin a comment. Likewise, a
<SPAN
CLASS="TOKEN"
>#</SPAN
> appears in <A
HREF="parameter-substitution.html#PSUB2"
>certain
parameter-substitution constructs</A
> and in <A
HREF="numerical-constants.html#NUMCONSTANTS"
> numerical constant expressions</A
>.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo "The # here does not begin a comment."
echo 'The # here does not begin a comment.'
echo The \# here does not begin a comment.
echo The # here begins a comment.
echo ${PATH#*:} # Parameter substitution, not a comment.
echo $(( 2#101011 )) # Base conversion, not a comment.
# Thanks, S.C.</PRE
></FONT
></TD
></TR
></TABLE
>
The standard <A
HREF="quoting.html#QUOTINGREF"
>quoting and
escape</A
> characters (" ' \) escape the #.
</P
></TD
></TR
></TABLE
></DIV
><P
>Certain <A
HREF="parameter-substitution.html#PSOREX1"
>pattern matching
operations</A
> also use the <SPAN
CLASS="TOKEN"
>#</SPAN
>.</P
></DD
><DT
><A
NAME="SEMICOLONREF"
></A
><SPAN
CLASS="TOKEN"
>;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Command separator [semicolon]. </B
>Permits putting two or more commands on the same
line.</P
></DIV
><P
> <TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo hello; echo there
if [ -x "$filename" ]; then # Note the space after the semicolon.
#+ ^^
echo "File $filename exists."; cp $filename $filename.bak
else # ^^
echo "File $filename not found."; touch $filename
fi; echo "File test complete."</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>Note that the <SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>;</SPAN
>"</SPAN
>
<A
HREF="moreadv.html#FINDREF0"
>sometimes needs to be
<I
CLASS="FIRSTTERM"
>escaped</I
></A
>.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>;;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Terminator in a <A
HREF="testbranch.html#CASEESAC1"
>case</A
> option [double semicolon]. </B
><A
NAME="DOUBLESEMICOLON"
></A
></P
></DIV
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>case "$variable" in
abc) echo "\$variable = abc" ;;
xyz) echo "\$variable = xyz" ;;
esac</PRE
></FONT
></TD
></TR
></TABLE
></P
></DD
><DT
><SPAN
CLASS="TOKEN"
>;;&#38;</SPAN
>, <SPAN
CLASS="TOKEN"
>;&#38;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="bashver4.html#NCTERM"
>Terminators</A
>
in a <I
CLASS="FIRSTTERM"
>case</I
> option (<A
HREF="bashver4.html#BASH4REF"
>version 4+</A
> of Bash). </B
></P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>.</SPAN
></DT
><DD
><P
><A
NAME="DOTREF"
></A
></P
><DIV
CLASS="FORMALPARA"
><P
><B
><SPAN
CLASS="QUOTE"
>"dot"</SPAN
> command [period]. </B
>Equivalent to <A
HREF="internal.html#SOURCEREF"
>source</A
> (see
<A
HREF="internal.html#EX38"
>Example 15-22</A
>). This is a bash <A
HREF="internal.html#BUILTINREF"
>builtin</A
>.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>.</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><SPAN
CLASS="QUOTE"
>"dot"</SPAN
>, as a component of a filename. </B
>When working with filenames, a leading dot is the prefix
of a <SPAN
CLASS="QUOTE"
>"hidden"</SPAN
> file, a file that an
<A
HREF="basic.html#LSREF"
>ls</A
> will not normally show.
<TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>touch .hidden-file</B
></TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>ls -l</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>total 10
-rw-r--r-- 1 bozo 4034 Jul 18 22:04 data1.addressbook
-rw-r--r-- 1 bozo 4602 May 25 13:58 data1.addressbook.bak
-rw-r--r-- 1 bozo 877 Dec 17 2000 employment.addressbook</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>ls -al</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>total 14
drwxrwxr-x 2 bozo bozo 1024 Aug 29 20:54 ./
drwx------ 52 bozo bozo 3072 Aug 29 20:51 ../
-rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.addressbook
-rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.addressbook.bak
-rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.addressbook
-rw-rw-r-- 1 bozo bozo 0 Aug 29 20:54 .hidden-file</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></DIV
><P
><A
NAME="DOTDIRECTORY"
></A
></P
><P
>When considering directory names, <I
CLASS="FIRSTTERM"
>a single
dot</I
> represents the current working directory,
and <I
CLASS="FIRSTTERM"
>two dots</I
> denote the parent
directory.</P
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>pwd</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/home/bozo/projects</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>cd .</B
></TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>pwd</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/home/bozo/projects</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>cd ..</B
></TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>pwd</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/home/bozo/</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>The <I
CLASS="FIRSTTERM"
>dot</I
> often appears as the
destination (directory) of a file movement command,
in this context meaning <I
CLASS="FIRSTTERM"
>current
directory</I
>.</P
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>cp /home/bozo/current_work/junk/* .</B
></TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
Copy all the <SPAN
CLASS="QUOTE"
>"junk"</SPAN
> files to
<A
HREF="internalvariables.html#PWDREF"
>$PWD</A
>.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>.</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><SPAN
CLASS="QUOTE"
>"dot"</SPAN
> character match. </B
>When <A
HREF="x17129.html#REGEXDOT"
>matching
characters</A
>, as part of a <A
HREF="regexp.html#REGEXREF"
>regular expression</A
>, a
<SPAN
CLASS="QUOTE"
>"dot"</SPAN
> <A
HREF="x17129.html#REGEXDOT"
>matches a
single character</A
>.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>"</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="varsubn.html#DBLQUO"
>partial
quoting</A
> [double quote]. </B
><EM
>"STRING"</EM
> preserves (from
interpretation) most of the special characters within
<EM
>STRING</EM
>. See <A
HREF="quoting.html"
>Chapter 5</A
>.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>'</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="varsubn.html#SNGLQUO"
>full
quoting</A
> [single quote]. </B
><EM
>'STRING'</EM
> preserves all special
characters within <EM
>STRING</EM
>. This is a
stronger form of quoting than <EM
>"STRING"</EM
>.
See <A
HREF="quoting.html"
>Chapter 5</A
>.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>,</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="ops.html#COMMAOP"
>comma
operator</A
>. </B
>The <I
CLASS="FIRSTTERM"
>comma operator</I
>
<A
NAME="AEN612"
HREF="#FTN.AEN612"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
>
links together a
series of arithmetic operations. All are evaluated,
but only the last one is returned.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>let "t2 = ((a = 9, 15 / 3))"
# Set "a = 9" and "t2 = 15 / 3"</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></DIV
><P
><A
NAME="COMMAOP2"
></A
>The <I
CLASS="FIRSTTERM"
>comma</I
>
operator can also concatenate strings.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>for file in /{,usr/}bin/*calc
# ^ Find all executable files ending in "calc"
#+ in /bin and /usr/bin directories.
do
if [ -x "$file" ]
then
echo $file
fi
done
# /bin/ipcalc
# /usr/bin/kcalc
# /usr/bin/oidcalc
# /usr/bin/oocalc
# Thank you, Rory Winston, for pointing this out.</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>,</SPAN
>, <SPAN
CLASS="TOKEN"
>,</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="bashver4.html#CASEMODPARAMSUB"
>Lowercase
conversion</A
> in <I
CLASS="FIRSTTERM"
>parameter substitution</I
>
(added in <A
HREF="bashver4.html#BASH4REF"
>version 4</A
> of Bash). </B
></P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>\</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="escapingsection.html#ESCP"
>escape</A
> [backslash]. </B
>A quoting mechanism for single characters.</P
></DIV
><P
><TT
CLASS="USERINPUT"
><B
>\X</B
></TT
>
<I
CLASS="FIRSTTERM"
>escapes</I
> the character
<EM
>X</EM
>. This has the effect of
<SPAN
CLASS="QUOTE"
>"quoting"</SPAN
> <EM
>X</EM
>, equivalent
to <EM
>'X'</EM
>. The <SPAN
CLASS="TOKEN"
>\</SPAN
> may
be used to quote <SPAN
CLASS="TOKEN"
>"</SPAN
> and <SPAN
CLASS="TOKEN"
>'</SPAN
>,
so they are expressed literally.</P
><P
>See <A
HREF="quoting.html"
>Chapter 5</A
> for an in-depth explanation
of escaped characters.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>/</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Filename path separator [forward slash]. </B
>Separates the components of a filename (as in
<TT
CLASS="FILENAME"
>/home/bozo/projects/Makefile</TT
>).</P
></DIV
><P
>This is also the division <A
HREF="ops.html#AROPS1"
>arithmetic operator</A
>.</P
></DD
><DT
><A
NAME="BACKTICKSREF"
></A
><SPAN
CLASS="TOKEN"
>`</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="commandsub.html#COMMANDSUBREF"
>command substitution</A
>. </B
>The <B
CLASS="COMMAND"
>`command`</B
> construct makes
available the output of <B
CLASS="COMMAND"
>command</B
>
for assignment to a variable. This is also known as
<A
HREF="commandsub.html#BACKQUOTESREF"
>backquotes</A
> or
backticks.</P
></DIV
></DD
><DT
><A
NAME="COLON0REF"
></A
><SPAN
CLASS="TOKEN"
>:</SPAN
></DT
><DD
><P
><A
NAME="NULLREF"
></A
></P
><DIV
CLASS="FORMALPARA"
><P
><B
>null command [colon]. </B
>This is the shell equivalent of a
<SPAN
CLASS="QUOTE"
>"NOP"</SPAN
> (<TT
CLASS="REPLACEABLE"
><I
>no op</I
></TT
>, a
do-nothing operation). It may be considered a synonym for
the shell builtin <A
HREF="internal.html#TRUEREF"
>true</A
>. The
<SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>:</SPAN
>"</SPAN
> command is itself a
<I
CLASS="FIRSTTERM"
>Bash</I
> <A
HREF="internal.html#BUILTINREF"
>builtin</A
>, and its <A
HREF="exit-status.html#EXITSTATUSREF"
>exit status</A
> is
<I
CLASS="FIRSTTERM"
>true</I
>
(<SPAN
CLASS="RETURNVALUE"
>0</SPAN
>).</P
></DIV
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>:
echo $? # 0</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>Endless loop:</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>while :
do
operation-1
operation-2
...
operation-n
done
# Same as:
# while true
# do
# ...
# done</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>Placeholder in if/then test:</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>if condition
then : # Do nothing and branch ahead
else # Or else ...
take-some-action
fi</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>Provide a placeholder where a binary operation is
expected, see <A
HREF="ops.html#ARITHOPS"
>Example 8-2</A
> and <A
HREF="parameter-substitution.html#DEFPARAM"
>default parameters</A
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>: ${username=`whoami`}
# ${username=`whoami`} Gives an error without the leading :
# unless "username" is a command or builtin...
: ${1?"Usage: $0 ARGUMENT"} # From "usage-message.sh example script.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>Provide a placeholder where a command is expected in a
<A
HREF="here-docs.html#HEREDOCREF"
>here document</A
>. See <A
HREF="here-docs.html#ANONHEREDOC"
>Example 19-10</A
>.</P
><P
>Evaluate string of variables using
<A
HREF="parameter-substitution.html#PARAMSUBREF"
>parameter substitution</A
>
(as in <A
HREF="parameter-substitution.html#EX6"
>Example 10-7</A
>).
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>: ${HOSTNAME?} ${USER?} ${MAIL?}
# Prints error message
#+ if one or more of essential environmental variables not set.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
><B
CLASS="COMMAND"
><A
HREF="parameter-substitution.html#EXPREPL1"
>Variable expansion / substring
replacement</A
></B
>.</P
><P
>In combination with the <SPAN
CLASS="TOKEN"
>&#62;</SPAN
> <A
HREF="io-redirection.html#IOREDIRREF"
>redirection operator</A
>,
truncates a file to zero length, without changing its
permissions. If the file did not previously exist,
creates it.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>: &#62; data.xxx # File "data.xxx" now empty.
# Same effect as cat /dev/null &#62;data.xxx
# However, this does not fork a new process, since ":" is a builtin.</PRE
></FONT
></TD
></TR
></TABLE
>
See also <A
HREF="textproc.html#EX12"
>Example 16-15</A
>.</P
><P
>In combination with the <SPAN
CLASS="TOKEN"
>&#62;&#62;</SPAN
>
redirection operator, has no effect on a pre-existing
target file (<TT
CLASS="USERINPUT"
><B
>: &#62;&#62; target_file</B
></TT
>).
If the file did not previously exist, creates it.</P
><DIV
CLASS="NOTE"
><P
></P
><TABLE
CLASS="NOTE"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
><A
NAME="REGFILEREF"
></A
>This applies to regular files,
not pipes, symlinks, and certain special files.</P
></TD
></TR
></TABLE
></DIV
><P
>May be used to begin a comment line, although this is not
recommended. Using <SPAN
CLASS="TOKEN"
>#</SPAN
> for a comment turns
off error checking for the remainder of that line, so
almost anything may appear in a comment. However,
this is not the case with
<SPAN
CLASS="TOKEN"
>:</SPAN
>.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>: This is a comment that generates an error, ( if [ $x -eq 3] ).</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>The <SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>:</SPAN
>"</SPAN
> serves as a <A
HREF="special-chars.html#FIELDREF"
>field</A
>
separator, in <A
HREF="files.html#DATAFILESREF1"
><TT
CLASS="FILENAME"
>/etc/passwd</TT
></A
>,
and in the <A
HREF="internalvariables.html#PATHREF"
>$PATH</A
> variable.
<TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo $PATH</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games</TT
></PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
><A
NAME="COLONFNAME"
></A
></P
><P
>A <I
CLASS="FIRSTTERM"
>colon</I
> is <A
HREF="functions.html#FSTRANGEREF"
>acceptable as a function name</A
>.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>:()
{
echo "The name of this function is "$FUNCNAME" "
# Why use a colon as a function name?
# It's a way of obfuscating your code.
}
:
# The name of this function is :</PRE
></FONT
></TD
></TR
></TABLE
>
This is not <A
HREF="portabilityissues.html"
>portable</A
>
behavior, and therefore not a recommended practice.
In fact, more recent releases of Bash do not permit
this usage. An underscore <B
CLASS="COMMAND"
>_</B
> works,
though.</P
><P
><A
NAME="COLONINFUNCTION"
></A
></P
><P
>A <I
CLASS="FIRSTTERM"
>colon</I
> can serve
as a placeholder in an otherwise empty
function.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>not_empty ()
{
:
} # Contains a : (null command), and so is not empty.</PRE
></FONT
></TD
></TR
></TABLE
></P
></DD
><DT
><A
NAME="NOTREF"
></A
><SPAN
CLASS="TOKEN"
>!</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>reverse (or negate) the sense of
a test or exit status [bang]. </B
>The <SPAN
CLASS="TOKEN"
>!</SPAN
> operator inverts the <A
HREF="exit-status.html#EXITSTATUSREF"
>exit status</A
>
of the command to which it is applied (see
<A
HREF="exit-status.html#NEGCOND"
>Example 6-2</A
>). It also inverts
the meaning of a test operator. This can, for
example, change the sense of <I
CLASS="FIRSTTERM"
>equal</I
>
( <A
HREF="comparison-ops.html#EQUALSIGNREF"
>=</A
>
) to <I
CLASS="FIRSTTERM"
>not-equal</I
> ( != ). The
<SPAN
CLASS="TOKEN"
>!</SPAN
> operator is a Bash <A
HREF="internal.html#KEYWORDREF"
>keyword</A
>.</P
></DIV
><P
>In a different context, the <SPAN
CLASS="TOKEN"
>!</SPAN
>
also appears in <A
HREF="ivr.html#IVRREF"
>indirect variable
references</A
>.</P
><P
>In yet another context, from the <I
CLASS="FIRSTTERM"
>command
line</I
>, the <SPAN
CLASS="TOKEN"
>!</SPAN
> invokes the
Bash <I
CLASS="FIRSTTERM"
>history mechanism</I
> (see <A
HREF="histcommands.html"
>Appendix L</A
>). Note that within a script,
the history mechanism is disabled.</P
></DD
><DT
><A
NAME="ASTERISKREF"
></A
><SPAN
CLASS="TOKEN"
>*</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>wild card [asterisk]. </B
>The <SPAN
CLASS="TOKEN"
>*</SPAN
> character serves as a <SPAN
CLASS="QUOTE"
>"wild
card"</SPAN
> for filename expansion in
<A
HREF="globbingref.html"
>globbing</A
>. By itself,
it matches every filename in a given directory.</P
></DIV
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo *</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>abs-book.sgml add-drive.sh agram.sh alias.sh</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
><A
NAME="ASTERISKREF2"
></A
></P
><P
>The <SPAN
CLASS="TOKEN"
>*</SPAN
> also represents <A
HREF="x17129.html#ASTERISKREG"
>any number
(or zero) characters</A
> in a <A
HREF="regexp.html#REGEXREF"
>regular expression</A
>.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>*</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="ops.html#AROPS1"
>arithmetic operator</A
>. </B
>In the context of arithmetic operations, the
<SPAN
CLASS="TOKEN"
>*</SPAN
> denotes multiplication.</P
></DIV
><P
><SPAN
CLASS="TOKEN"
>**</SPAN
> A double asterisk can represent the
<A
HREF="ops.html#EXPONENTIATIONREF"
>exponentiation</A
>
operator or <A
HREF="bashver4.html#GLOBSTARREF"
>extended
file-match</A
> <I
CLASS="FIRSTTERM"
>globbing</I
>.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>?</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>test operator. </B
>Within certain expressions, the <SPAN
CLASS="TOKEN"
>?</SPAN
> indicates
a test for a condition.</P
></DIV
><P
><A
NAME="CSTRINARY"
></A
></P
><P
>In a <A
HREF="dblparens.html"
>double-parentheses
construct</A
>, the <SPAN
CLASS="TOKEN"
>?</SPAN
>
can serve as an element of a C-style
<I
CLASS="FIRSTTERM"
>trinary</I
> operator.
<A
NAME="AEN888"
HREF="#FTN.AEN888"
><SPAN
CLASS="footnote"
>[2]</SPAN
></A
>
</P
><P
><TT
CLASS="VARNAME"
>condition</TT
><B
CLASS="COMMAND"
>?</B
><TT
CLASS="VARNAME"
>result-if-true</TT
><B
CLASS="COMMAND"
>:</B
><TT
CLASS="VARNAME"
>result-if-false</TT
></P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>(( var0 = var1&#60;98?9:21 ))
# ^ ^
# if [ "$var1" -lt 98 ]
# then
# var0=9
# else
# var0=21
# fi</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>In a <A
HREF="parameter-substitution.html#PARAMSUBREF"
>parameter
substitution</A
> expression, the <SPAN
CLASS="TOKEN"
>?</SPAN
>
<A
HREF="parameter-substitution.html#QERRMSG"
>tests whether a variable has been
set</A
>.</P
></DD
><DT
><A
NAME="WILDCARDQU"
></A
><SPAN
CLASS="TOKEN"
>?</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>wild card. </B
><A
NAME="QUEXWC"
></A
>The <SPAN
CLASS="TOKEN"
>?</SPAN
> character
serves as a single-character <SPAN
CLASS="QUOTE"
>"wild card"</SPAN
>
for filename expansion in <A
HREF="globbingref.html"
>globbing</A
>, as well as <A
HREF="x17129.html#QUEXREGEX"
>representing one character</A
>
in an <A
HREF="x17129.html#EXTREGEX"
>extended regular
expression</A
>.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>$</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="varsubn.html"
>Variable
substitution</A
> (contents of a variable). </B
> <TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>var1=5
var2=23skidoo
echo $var1 # 5
echo $var2 # 23skidoo</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></DIV
><P
><A
NAME="VARPREFIXREF"
></A
></P
><P
>A <SPAN
CLASS="TOKEN"
>$</SPAN
> prefixing a variable name
indicates the <I
CLASS="FIRSTTERM"
>value</I
> the variable
holds.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>$</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>end-of-line. </B
>In a <A
HREF="regexp.html#REGEXREF"
>regular expression</A
>, a
<SPAN
CLASS="QUOTE"
>"$"</SPAN
> addresses the <A
HREF="x17129.html#DOLLARSIGNREF"
>end of a line</A
> of
text.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>${}</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="parameter-substitution.html#PARAMSUBREF"
>Parameter
substitution</A
>. </B
></P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>$' ... '</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="escapingsection.html#STRQ"
>Quoted string
expansion</A
>. </B
>This construct expands single or multiple
escaped octal or hex values into ASCII
<A
NAME="AEN1001"
HREF="#FTN.AEN1001"
><SPAN
CLASS="footnote"
>[3]</SPAN
></A
>
or <A
HREF="bashver4.html#UNICODEREF"
>Unicode</A
>
characters.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>$*</SPAN
>, <SPAN
CLASS="TOKEN"
>$@</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="internalvariables.html#APPREF"
>positional
parameters</A
>. </B
></P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>$?</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>exit status variable. </B
>The <A
HREF="exit-status.html#EXSREF"
>$? variable</A
>
holds the <A
HREF="exit-status.html#EXITSTATUSREF"
>exit status</A
>
of a command, a <A
HREF="functions.html#FUNCTIONREF"
>function</A
>,
or of the script itself.</P
></DIV
></DD
><DT
><A
NAME="PROCESSIDREF"
></A
><SPAN
CLASS="TOKEN"
>$$</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>process ID variable. </B
>The <A
HREF="internalvariables.html#PROCCID"
>$$ variable</A
>
holds the <I
CLASS="FIRSTTERM"
>process ID</I
>
<A
NAME="AEN1071"
HREF="#FTN.AEN1071"
><SPAN
CLASS="footnote"
>[4]</SPAN
></A
>
of the script in which it appears.</P
></DIV
></DD
><DT
><A
NAME="PARENSREF"
></A
><SPAN
CLASS="TOKEN"
>()</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>command group. </B
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>(a=hello; echo $a)</PRE
></FONT
></TD
></TR
></TABLE
></P
></DIV
><DIV
CLASS="IMPORTANT"
><P
></P
><TABLE
CLASS="IMPORTANT"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/important.gif"
HSPACE="5"
ALT="Important"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>A listing of commands within
<TT
CLASS="REPLACEABLE"
><I
>parentheses</I
></TT
> starts a <A
HREF="subshells.html#SUBSHELLSREF"
>subshell</A
>.</P
><P
>Variables inside parentheses, within the subshell, are not
visible to the rest of the script. The parent process,
the script, <A
HREF="subshells.html#PARVIS"
>cannot read variables
created in the child process</A
>, the subshell.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>a=123
( a=321; )
echo "a = $a" # a = 123
# "a" within parentheses acts like a local variable.</PRE
></FONT
></TD
></TR
></TABLE
></P
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="FORMALPARA"
><P
><B
>array initialization. </B
> <A
NAME="ARRAYINIT1"
></A
>
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>Array=(element1 element2 element3)</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>{xxx,yyy,zzz,...}</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Brace expansion. </B
><A
NAME="BRACEEXPREF"
></A
>
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo \"{These,words,are,quoted}\" # " prefix and suffix
# "These" "words" "are" "quoted"
cat {file1,file2,file3} &#62; combined_file
# Concatenates the files file1, file2, and file3 into combined_file.
cp file22.{txt,backup}
# Copies "file22.txt" to "file22.backup"</PRE
></FONT
></TD
></TR
></TABLE
></P
></DIV
><P
>A command may act upon a comma-separated list of file specs within
<TT
CLASS="REPLACEABLE"
><I
>braces</I
></TT
>.
<A
NAME="AEN1124"
HREF="#FTN.AEN1124"
><SPAN
CLASS="footnote"
>[5]</SPAN
></A
>
Filename expansion (<A
HREF="globbingref.html"
>globbing</A
>)
applies to the file specs between the braces.</P
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/caution.gif"
HSPACE="5"
ALT="Caution"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>No spaces allowed within the braces
<EM
>unless</EM
> the spaces are quoted or escaped.</P
><P
><TT
CLASS="USERINPUT"
><B
>echo {file1,file2}\ :{\ A," B",' C'}</B
></TT
></P
><P
><TT
CLASS="COMPUTEROUTPUT"
>file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C</TT
></P
></TD
></TR
></TABLE
></DIV
></DD
><DT
><A
NAME="BRACEEXPREF33"
></A
><SPAN
CLASS="TOKEN"
>{a..z}</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Extended Brace expansion. </B
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z
# Echoes characters between a and z.
echo {0..3} # 0 1 2 3
# Echoes characters between 0 and 3.
base64_charset=( {A..Z} {a..z} {0..9} + / = )
# Initializing an array, using extended brace expansion.
# From vladz's "base64.sh" example script.</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></DIV
><P
>The <I
CLASS="FIRSTTERM"
>{a..z}</I
>
<A
HREF="bashver3.html#BRACEEXPREF3"
>extended brace
expansion</A
> construction is a feature introduced
in <A
HREF="bashver3.html#BASH3REF"
>version 3</A
> of
<I
CLASS="FIRSTTERM"
>Bash</I
>.</P
></DD
><DT
><A
NAME="CODEBLOCKREF"
></A
><SPAN
CLASS="TOKEN"
>{}</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Block of code [curly brackets]. </B
>Also referred to as an <I
CLASS="FIRSTTERM"
>inline group</I
>,
this construct, in effect, creates an <I
CLASS="FIRSTTERM"
>anonymous
function</I
> (a function without a
name). However, unlike in a <SPAN
CLASS="QUOTE"
>"standard"</SPAN
> <A
HREF="functions.html#FUNCTIONREF"
>function</A
>, the variables
inside a code block remain visible to the remainder of the
script.</P
></DIV
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>{ local a;
a=123; }</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>bash: local: can only be used in a
function</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
> </P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>a=123
{ a=321; }
echo "a = $a" # a = 321 (value inside code block)
# Thanks, S.C.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
><A
NAME="BLOCKIO"
></A
></P
><P
>The code block enclosed in braces may have <A
HREF="io-redirection.html#IOREDIRREF"
>I/O redirected</A
> to and from
it.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="EX8"
></A
><P
><B
>Example 3-1. Code blocks and I/O redirection</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# Reading lines in /etc/fstab.
File=/etc/fstab
{
read line1
read line2
} &#60; $File
echo "First line in $File is:"
echo "$line1"
echo
echo "Second line in $File is:"
echo "$line2"
exit 0
# Now, how do you parse the separate fields of each line?
# Hint: use awk, or . . .
# . . . Hans-Joerg Diers suggests using the "set" Bash builtin.</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><P
><A
NAME="BLOCKIO2"
></A
></P
><DIV
CLASS="EXAMPLE"
><A
NAME="RPMCHECK"
></A
><P
><B
>Example 3-2. Saving the output of a code block to a file</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# rpm-check.sh
# Queries an rpm file for description, listing,
#+ and whether it can be installed.
# Saves output to a file.
#
# This script illustrates using a code block.
SUCCESS=0
E_NOARGS=65
if [ -z "$1" ]
then
echo "Usage: `basename $0` rpm-file"
exit $E_NOARGS
fi
{ # Begin code block.
echo
echo "Archive Description:"
rpm -qpi $1 # Query description.
echo
echo "Archive Listing:"
rpm -qpl $1 # Query listing.
echo
rpm -i --test $1 # Query whether rpm file can be installed.
if [ "$?" -eq $SUCCESS ]
then
echo "$1 can be installed."
else
echo "$1 cannot be installed."
fi
echo # End code block.
} &#62; "$1.test" # Redirects output of everything in block to file.
echo "Results of rpm test in file $1.test"
# See rpm man page for explanation of options.
exit 0</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NOTE"
><P
></P
><TABLE
CLASS="NOTE"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>Unlike a command group within (parentheses),
as above, a code block enclosed by {braces} will
<EM
>not</EM
> normally launch a <A
HREF="subshells.html#SUBSHELLSREF"
>subshell</A
>.
<A
NAME="AEN1199"
HREF="#FTN.AEN1199"
><SPAN
CLASS="footnote"
>[6]</SPAN
></A
>
</P
><P
>It is possible to <A
HREF="loops1.html#ITERATIONREF"
>iterate</A
> a code block
using a <A
HREF="loops1.html#NODODONE"
>non-standard
<I
CLASS="FIRSTTERM"
>for-loop</I
></A
>.</P
></TD
></TR
></TABLE
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>{}</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>placeholder for text. </B
>Used after <A
HREF="moreadv.html#XARGSCURLYREF"
>xargs
<TT
CLASS="OPTION"
>-i</TT
></A
> (<I
CLASS="FIRSTTERM"
>replace
strings</I
> option). The <SPAN
CLASS="TOKEN"
>{}</SPAN
> double
curly brackets are a placeholder for output text.</P
></DIV
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>ls . | xargs -i -t cp ./{} $1
# ^^ ^^
# From "ex42.sh" (copydir.sh) example.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
><A
NAME="SEMICOLONESC"
></A
></P
></DD
><DT
><SPAN
CLASS="TOKEN"
>{} \;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>pathname. </B
>Mostly used in <A
HREF="moreadv.html#FINDREF"
>find</A
>
constructs. This is <EM
>not</EM
> a shell
<A
HREF="internal.html#BUILTINREF"
>builtin</A
>.</P
></DIV
><TABLE
CLASS="SIDEBAR"
BORDER="1"
CELLPADDING="5"
><TR
><TD
><DIV
CLASS="SIDEBAR"
><A
NAME="AEN1234"
></A
><P
></P
><P
><A
NAME="PATHNAMEREF"
></A
></P
><P
>Definition: A <I
CLASS="FIRSTTERM"
>pathname</I
>
is a <I
CLASS="FIRSTTERM"
>filename</I
> that includes the
complete <A
HREF="internalvariables.html#PATHREF"
>path</A
>. As an example,
<TT
CLASS="FILENAME"
>/home/bozo/Notes/Thursday/schedule.txt</TT
>.
This is sometimes referred to as the <I
CLASS="FIRSTTERM"
>absolute
path</I
>.</P
><P
></P
></DIV
></TD
></TR
></TABLE
><DIV
CLASS="NOTE"
><P
></P
><TABLE
CLASS="NOTE"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>The <SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>;</SPAN
>"</SPAN
> ends
the <TT
CLASS="OPTION"
>-exec</TT
> option of a
<B
CLASS="COMMAND"
>find</B
> command sequence. It needs
to be escaped to protect it from interpretation by the
shell.</P
></TD
></TR
></TABLE
></DIV
></DD
><DT
><A
NAME="LEFTBRACKET"
></A
><SPAN
CLASS="TOKEN"
>[ ]</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>test. </B
><A
NAME="BRACKTEST"
></A
></P
></DIV
><P
><A
HREF="tests.html#IFTHEN"
>Test</A
> expression between
<B
CLASS="COMMAND"
>[ ]</B
>. Note that <B
CLASS="COMMAND"
>[</B
>
is part of the shell <I
CLASS="FIRSTTERM"
>builtin</I
> <A
HREF="testconstructs.html#TTESTREF"
>test</A
> (and a synonym for it),
<EM
>not</EM
> a link to the external command
<TT
CLASS="FILENAME"
>/usr/bin/test</TT
>.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>[[ ]]</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>test. </B
></P
></DIV
><P
>Test expression between <SPAN
CLASS="TOKEN"
>[[ ]]</SPAN
>. More
flexible than the single-bracket <SPAN
CLASS="TOKEN"
>[ ]</SPAN
> test,
this is a shell <A
HREF="internal.html#KEYWORDREF"
>keyword</A
>.</P
><P
>See the
discussion on the <A
HREF="testconstructs.html#DBLBRACKETS"
>[[ ... ]]
construct</A
>.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>[ ]</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>array element. </B
></P
></DIV
><P
>In the context of an <A
HREF="arrays.html#ARRAYREF"
>array</A
>,
brackets set off the numbering of each element of that array.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>Array[1]=slot_1
echo ${Array[1]}</PRE
></FONT
></TD
></TR
></TABLE
></P
></DD
><DT
><SPAN
CLASS="TOKEN"
>[ ]</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>range of characters. </B
></P
></DIV
><P
>As part of a <A
HREF="regexp.html#REGEXREF"
>regular
expression</A
>, brackets delineate a <A
HREF="x17129.html#BRACKETSREF"
>range of characters</A
> to
match.</P
></DD
><DT
><A
NAME="BRACKETARITH"
></A
><SPAN
CLASS="TOKEN"
>$[ ... ]</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>integer expansion. </B
></P
></DIV
><P
>Evaluate integer expression between
<SPAN
CLASS="TOKEN"
>$[ ]</SPAN
>.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>a=3
b=7
echo $[$a+$b] # 10
echo $[$a*$b] # 21</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>Note that this usage is <EM
>deprecated</EM
>,
and has been replaced by the
<A
HREF="dblparens.html"
>(( ... ))</A
> construct.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>(( ))</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>integer expansion. </B
></P
></DIV
><P
>Expand and evaluate integer expression between
<SPAN
CLASS="TOKEN"
>(( ))</SPAN
>.</P
><P
>See the discussion on the <A
HREF="dblparens.html"
>(( ... )) construct</A
>.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>&#62;</SPAN
> <SPAN
CLASS="TOKEN"
>&#38;&#62;</SPAN
> <SPAN
CLASS="TOKEN"
>&#62;&#38;</SPAN
> <SPAN
CLASS="TOKEN"
>&#62;&#62;</SPAN
> <SPAN
CLASS="TOKEN"
>&#60;</SPAN
> <SPAN
CLASS="TOKEN"
>&#60;&#62;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="io-redirection.html#IOREDIRREF"
>redirection</A
>. </B
></P
></DIV
><P
><TT
CLASS="USERINPUT"
><B
>scriptname &#62;filename</B
></TT
> redirects the output of
<TT
CLASS="FILENAME"
>scriptname</TT
> to file
<TT
CLASS="FILENAME"
>filename</TT
>. Overwrite
<TT
CLASS="FILENAME"
>filename</TT
> if it already exists.</P
><P
><A
NAME="REDIROUTERROR"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>command &#38;&#62;filename</B
></TT
> redirects
both the <A
HREF="ioredirintro.html#STDINOUTDEF"
><TT
CLASS="FILENAME"
>stdout</TT
></A
>
and the
<TT
CLASS="FILENAME"
>stderr</TT
> of <TT
CLASS="FILENAME"
>command</TT
>
to <TT
CLASS="FILENAME"
>filename</TT
>.</P
><DIV
CLASS="NOTE"
><P
></P
><TABLE
CLASS="NOTE"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
> <A
NAME="DEVNULLREDIRECT"
></A
>
This is useful for suppressing output when
testing for a condition. For example, let us
test whether a certain command exists.
</P
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>type bogus_command &#38;&#62;/dev/null</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
></TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo $?</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>1</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>Or in a script:</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>command_test () { type "$1" &#38;&#62;/dev/null; }
# ^
cmd=rmdir # Legitimate command.
command_test $cmd; echo $? # 0
cmd=bogus_command # Illegitimate command
command_test $cmd; echo $? # 1</PRE
></FONT
></TD
></TR
></TABLE
></P
></TD
></TR
></TABLE
></DIV
><P
><A
NAME="REDIROUTERROR2"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>command &#62;&#38;2</B
></TT
> redirects
<TT
CLASS="FILENAME"
>stdout</TT
> of <TT
CLASS="FILENAME"
>command</TT
>
to <TT
CLASS="FILENAME"
>stderr</TT
>.</P
><P
><TT
CLASS="USERINPUT"
><B
>scriptname &#62;&#62;filename</B
></TT
> appends
the output of <TT
CLASS="FILENAME"
>scriptname</TT
>
to file <TT
CLASS="FILENAME"
>filename</TT
>. If
<TT
CLASS="FILENAME"
>filename</TT
> does not already exist,
it is created.</P
><P
><A
NAME="REDIRRW"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>[i]&#60;&#62;filename</B
></TT
>
opens file <TT
CLASS="FILENAME"
>filename</TT
> for reading
and writing, and assigns <A
HREF="io-redirection.html#FDREF"
>file
descriptor</A
> <SPAN
CLASS="TOKEN"
>i</SPAN
> to it. If
<TT
CLASS="FILENAME"
>filename</TT
> does not exist, it is
created.</P
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="process-sub.html#PROCESSSUBREF"
>process substitution</A
>. </B
></P
></DIV
><P
><TT
CLASS="USERINPUT"
><B
>(command)&#62;</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>&#60;(command)</B
></TT
></P
><P
><A
HREF="comparison-ops.html#LTREF"
>In a different context</A
>,
the <SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>&#60;</SPAN
>"</SPAN
> and
<SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>&#62;</SPAN
>"</SPAN
> characters act
as <A
HREF="comparison-ops.html#SCOMPARISON1"
>string comparison
operators</A
>.</P
><P
><A
HREF="comparison-ops.html#INTLT"
>In yet another context</A
>,
the <SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>&#60;</SPAN
>"</SPAN
> and
<SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>&#62;</SPAN
>"</SPAN
> characters act
as <A
HREF="comparison-ops.html#ICOMPARISON1"
>integer comparison
operators</A
>. See also <A
HREF="moreadv.html#EX45"
>Example 16-9</A
>.</P
></DD
><DT
><A
NAME="HEREDOCRRREF"
></A
><SPAN
CLASS="TOKEN"
>&#60;&#60;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>redirection used in a <A
HREF="here-docs.html#HEREDOCREF"
>here document</A
>. </B
></P
></DIV
></DD
><DT
><A
NAME="HERESTRINGREF"
></A
><SPAN
CLASS="TOKEN"
>&#60;&#60;&#60;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>redirection used in a <A
HREF="x17837.html#HERESTRINGSREF"
>here string</A
>. </B
></P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>&#60;</SPAN
>, <SPAN
CLASS="TOKEN"
>&#62;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="comparison-ops.html#LTREF"
>ASCII
comparison</A
>. </B
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>veg1=carrots
veg2=tomatoes
if [[ "$veg1" &#60; "$veg2" ]]
then
echo "Although $veg1 precede $veg2 in the dictionary,"
echo -n "this does not necessarily imply anything "
echo "about my culinary preferences."
else
echo "What kind of dictionary are you using, anyhow?"
fi</PRE
></FONT
></TD
></TR
></TABLE
></P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>\&#60;</SPAN
>, <SPAN
CLASS="TOKEN"
>\&#62;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="x17129.html#ANGLEBRAC"
>word
boundary</A
> in a <A
HREF="regexp.html#REGEXREF"
>regular
expression</A
>. </B
></P
></DIV
><P
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>grep '\&#60;the\&#62;' textfile</B
></TT
></P
></DD
><DT
><SPAN
CLASS="TOKEN"
>|</SPAN
></DT
><DD
><P
><A
NAME="PIPEREF"
></A
></P
><DIV
CLASS="FORMALPARA"
><P
><B
>pipe. </B
>Passes the output (<TT
CLASS="FILENAME"
>stdout</TT
>)
of a previous command to the input
(<TT
CLASS="FILENAME"
>stdin</TT
>) of the next one, or
to the shell. This is a method of chaining commands
together.</P
></DIV
><P
> <TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo ls -l | sh
# Passes the output of "echo ls -l" to the shell,
#+ with the same result as a simple "ls -l".
cat *.lst | sort | uniq
# Merges and sorts all ".lst" files, then deletes duplicate lines.</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><TABLE
CLASS="SIDEBAR"
BORDER="1"
CELLPADDING="5"
><TR
><TD
><DIV
CLASS="SIDEBAR"
><A
NAME="AEN1555"
></A
><P
></P
><P
> A pipe, as a classic method of interprocess
communication, sends the <TT
CLASS="FILENAME"
>stdout</TT
>
of one <A
HREF="special-chars.html#PROCESSREF"
>process</A
> to the
<TT
CLASS="FILENAME"
>stdin</TT
> of another. In a typical case,
a command, such as <A
HREF="basic.html#CATREF"
>cat</A
> or
<A
HREF="internal.html#ECHOREF"
>echo</A
>, pipes a stream of
data to a
<A
NAME="FILTERDEF"
></A
>
<I
CLASS="FIRSTTERM"
>filter</I
>, a command that
transforms its input for processing.
<A
NAME="AEN1564"
HREF="#FTN.AEN1564"
><SPAN
CLASS="footnote"
>[7]</SPAN
></A
>
</P
><P
>
<TT
CLASS="USERINPUT"
><B
>cat $filename1 $filename2 | grep $search_word</B
></TT
>
</P
><P
>For an interesting note on the complexity of using UNIX
pipes, see <A
HREF="http://www.faqs.org/faqs/unix-faq/faq/part3/"
TARGET="_top"
>the UNIX FAQ,
Part 3</A
>.</P
><P
></P
></DIV
></TD
></TR
></TABLE
><P
><A
NAME="UCREF"
></A
>The output of a command or commands
may be piped to a script.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# uppercase.sh : Changes input to uppercase.
tr 'a-z' 'A-Z'
# Letter ranges must be quoted
#+ to prevent filename generation from single-letter filenames.
exit 0</PRE
></FONT
></TD
></TR
></TABLE
>
Now, let us pipe the output of <B
CLASS="COMMAND"
>ls -l</B
> to this
script.
<TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>ls -l | ./uppercase.sh</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>-RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT
-RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT
-RW-R--R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><DIV
CLASS="NOTE"
><P
></P
><TABLE
CLASS="NOTE"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>The <TT
CLASS="FILENAME"
>stdout</TT
> of each process in
a pipe must be read as the <TT
CLASS="FILENAME"
>stdin</TT
>
of the next. If this is not the case, the data stream
will <I
CLASS="FIRSTTERM"
>block</I
>, and the pipe will not
behave as expected.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>cat file1 file2 | ls -l | sort
# The output from "cat file1 file2" disappears.</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>A pipe runs as a <A
HREF="othertypesv.html#CHILDREF"
>child
process</A
>, and therefore cannot alter script
variables.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>variable="initial_value"
echo "new_value" | read variable
echo "variable = $variable" # variable = initial_value</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>If one of the commands in the pipe
aborts, this prematurely terminates execution of the
pipe. Called a <I
CLASS="FIRSTTERM"
>broken pipe</I
>, this
condition sends a <TT
CLASS="REPLACEABLE"
><I
>SIGPIPE</I
></TT
> <A
HREF="debugging.html#SIGNALD"
>signal</A
>.</P
></TD
></TR
></TABLE
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>&#62;|</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>force redirection (even if
the <A
HREF="options.html#NOCLOBBERREF"
>noclobber option</A
>
is set). </B
>This will forcibly overwrite an existing file.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>||</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="ops.html#ORREF"
>OR logical operator</A
>. </B
>In a <A
HREF="testconstructs.html#TESTCONSTRUCTS1"
>test
construct</A
>, the <SPAN
CLASS="TOKEN"
>||</SPAN
> operator causes
a return of <SPAN
CLASS="RETURNVALUE"
>0</SPAN
> (success) if
<EM
>either</EM
> of the linked test conditions
is true.</P
></DIV
></DD
><DT
><A
NAME="BGJOB"
></A
><SPAN
CLASS="TOKEN"
>&#38;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Run job in background. </B
>A command followed by an <SPAN
CLASS="TOKEN"
>&#38;</SPAN
>
will run in the background.</P
></DIV
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>sleep 10 &#38;</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>[1] 850</TT
>
<TT
CLASS="COMPUTEROUTPUT"
>[1]+ Done sleep 10</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>Within a script, commands and even <A
HREF="loops1.html#FORLOOPREF1"
>loops</A
> may run in the
background.</P
><P
><A
NAME="BGLOOP0"
></A
></P
><DIV
CLASS="EXAMPLE"
><A
NAME="BGLOOP"
></A
><P
><B
>Example 3-3. Running a loop in the background</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# background-loop.sh
for i in 1 2 3 4 5 6 7 8 9 10 # First loop.
do
echo -n "$i "
done &#38; # Run this loop in background.
# Will sometimes execute after second loop.
echo # This 'echo' sometimes will not display.
for i in 11 12 13 14 15 16 17 18 19 20 # Second loop.
do
echo -n "$i "
done
echo # This 'echo' sometimes will not display.
# ======================================================
# The expected output from the script:
# 1 2 3 4 5 6 7 8 9 10
# 11 12 13 14 15 16 17 18 19 20
# Sometimes, though, you get:
# 11 12 13 14 15 16 17 18 19 20
# 1 2 3 4 5 6 7 8 9 10 bozo $
# (The second 'echo' doesn't execute. Why?)
# Occasionally also:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# (The first 'echo' doesn't execute. Why?)
# Very rarely something like:
# 11 12 13 1 2 3 4 5 6 7 8 9 10 14 15 16 17 18 19 20
# The foreground loop preempts the background one.
exit 0
# Nasimuddin Ansari suggests adding sleep 1
#+ after the echo -n "$i" in lines 6 and 14,
#+ for some real fun.</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/caution.gif"
HSPACE="5"
ALT="Caution"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>A command run in the background within a
script may cause the script to hang, waiting
for a keystroke. Fortunately, there is a <A
HREF="x9644.html#WAITHANG"
>remedy</A
> for this.</P
></TD
></TR
></TABLE
></DIV
></DD
><DT
><A
NAME="LOGICALAND"
></A
><SPAN
CLASS="TOKEN"
>&#38;&#38;</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="ops.html#LOGOPS1"
>AND logical
operator</A
>. </B
>In a <A
HREF="testconstructs.html#TESTCONSTRUCTS1"
>test
construct</A
>, the <SPAN
CLASS="TOKEN"
>&#38;&#38;</SPAN
> operator causes
a return of <SPAN
CLASS="RETURNVALUE"
>0</SPAN
> (success) only if
<EM
>both</EM
> the linked test conditions
are true.</P
></DIV
></DD
><DT
><A
NAME="DASHREF"
></A
><SPAN
CLASS="TOKEN"
>-</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>option, prefix. </B
>Option flag for a command or filter. Prefix for
an operator. Prefix for a <A
HREF="parameter-substitution.html#DEFPARAM1"
>default parameter</A
>
in <A
HREF="parameter-substitution.html#PARAMSUBREF"
>parameter
substitution</A
>.</P
></DIV
><P
><TT
CLASS="USERINPUT"
><B
>COMMAND -[Option1][Option2][...]</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>ls -al</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>sort -dfu $filename</B
></TT
></P
><P
> <TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>if [ $file1 -ot $file2 ]
then # ^
echo "File $file1 is older than $file2."
fi
if [ "$a" -eq "$b" ]
then # ^
echo "$a is equal to $b."
fi
if [ "$c" -eq 24 -a "$d" -eq 47 ]
then # ^ ^
echo "$c equals 24 and $d equals 47."
fi
param2=${param1:-$DEFAULTVAL}
# ^</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
><A
NAME="DOUBLEDASHREF"
></A
></P
><P
><B
CLASS="COMMAND"
>--</B
></P
><P
>The <I
CLASS="FIRSTTERM"
>double-dash</I
>
<TT
CLASS="OPTION"
>--</TT
> prefixes <I
CLASS="FIRSTTERM"
>long</I
>
(verbatim) options to commands.</P
><P
><TT
CLASS="USERINPUT"
><B
>sort --ignore-leading-blanks</B
></TT
></P
><P
>Used with a <A
HREF="internal.html#BUILTINREF"
>Bash
builtin</A
>, it means the <I
CLASS="FIRSTTERM"
>end of
options</I
> to that particular command.</P
><DIV
CLASS="TIP"
><P
></P
><TABLE
CLASS="TIP"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/tip.gif"
HSPACE="5"
ALT="Tip"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>This provides a handy means of removing
files whose <EM
>names begin with a dash</EM
>.
<TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>ls -l</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>-rw-r--r-- 1 bozo bozo 0 Nov 25 12:29 -badname</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>rm -- -badname</B
></TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>ls -l</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>total 0</TT
></PRE
></FONT
></TD
></TR
></TABLE
>
</P
></TD
></TR
></TABLE
></DIV
><P
>The <I
CLASS="FIRSTTERM"
>double-dash</I
> is also used in
conjunction with <A
HREF="internal.html#SETREF"
>set</A
>.</P
><P
><TT
CLASS="USERINPUT"
><B
>set -- $variable</B
></TT
> (as in <A
HREF="internal.html#SETPOS"
>Example 15-18</A
>)</P
></DD
><DT
><A
NAME="DASHREF2"
></A
><SPAN
CLASS="TOKEN"
>-</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>redirection from/to <TT
CLASS="FILENAME"
>stdin</TT
> or <TT
CLASS="FILENAME"
>stdout</TT
> [dash]. </B
><A
NAME="COXEX"
></A
></P
></DIV
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>cat -</B
></TT
>
<TT
CLASS="USERINPUT"
><B
>abc</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>abc</TT
>
<TT
CLASS="COMPUTEROUTPUT"
>...</TT
>
<TT
CLASS="USERINPUT"
><B
>Ctl-D</B
></TT
></PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>As expected, <TT
CLASS="USERINPUT"
><B
>cat -</B
></TT
> echoes
<TT
CLASS="FILENAME"
>stdin</TT
>, in this case keyboarded user input,
to <TT
CLASS="FILENAME"
>stdout</TT
>. But, does I/O redirection using
<B
CLASS="COMMAND"
>-</B
> have real-world applications?</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>(cd /source/directory &#38;&#38; tar cf - . ) | (cd /dest/directory &#38;&#38; tar xpvf -)
# Move entire file tree from one directory to another
# [courtesy Alan Cox &#60;a.cox@swansea.ac.uk&#62;, with a minor change]
# 1) cd /source/directory
# Source directory, where the files to be moved are.
# 2) &#38;&#38;
# "And-list": if the 'cd' operation successful,
# then execute the next command.
# 3) tar cf - .
# The 'c' option 'tar' archiving command creates a new archive,
# the 'f' (file) option, followed by '-' designates the target file
# as stdout, and do it in current directory tree ('.').
# 4) |
# Piped to ...
# 5) ( ... )
# a subshell
# 6) cd /dest/directory
# Change to the destination directory.
# 7) &#38;&#38;
# "And-list", as above
# 8) tar xpvf -
# Unarchive ('x'), preserve ownership and file permissions ('p'),
# and send verbose messages to stdout ('v'),
# reading data from stdin ('f' followed by '-').
#
# Note that 'x' is a command, and 'p', 'v', 'f' are options.
#
# Whew!
# More elegant than, but equivalent to:
# cd source/directory
# tar cf - . | (cd ../dest/directory; tar xpvf -)
#
# Also having same effect:
# cp -a /source/directory/* /dest/directory
# Or:
# cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
# If there are hidden files in /source/directory.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf -
# --uncompress tar file-- | --then pass it to "tar"--
# If "tar" has not been patched to handle "bunzip2",
#+ this needs to be done in two discrete steps, using a pipe.
# The purpose of the exercise is to unarchive "bzipped" kernel source.</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>Note that in this context the <SPAN
CLASS="QUOTE"
>"-"</SPAN
> is not
itself a Bash operator, but rather an option recognized by
certain UNIX utilities that write to
<TT
CLASS="FILENAME"
>stdout</TT
>, such as <B
CLASS="COMMAND"
>tar</B
>,
<B
CLASS="COMMAND"
>cat</B
>, etc.</P
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo "whatever" | cat -</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>whatever</TT
> </PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>Where a filename is expected,
<TT
CLASS="REPLACEABLE"
><I
>-</I
></TT
> redirects output to
<TT
CLASS="FILENAME"
>stdout</TT
> (sometimes seen with
<TT
CLASS="USERINPUT"
><B
>tar cf</B
></TT
>), or accepts input from
<TT
CLASS="FILENAME"
>stdin</TT
>, rather than from a file.
<A
NAME="FILTERDASH"
></A
>
This is a method of using a file-oriented utility as a
filter in a pipe.</P
><P
> <TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>file</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>Usage: file [-bciknvzL] [-f namefile] [-m magicfiles] file...</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
By itself on the command-line, <A
HREF="filearchiv.html#FILEREF"
>file</A
> fails with an error message.
</P
><P
> Add a <SPAN
CLASS="QUOTE"
>"-"</SPAN
> for a more useful result. This causes the
shell to await user input.
<TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>file -</B
></TT
>
<TT
CLASS="USERINPUT"
><B
>abc</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>standard input: ASCII text</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>file -</B
></TT
>
<TT
CLASS="USERINPUT"
><B
>#!/bin/bash</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>standard input: Bourne-Again shell script text executable</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
Now the command accepts input from <TT
CLASS="FILENAME"
>stdin</TT
>
and analyzes it.
</P
><P
>The <SPAN
CLASS="QUOTE"
>"-"</SPAN
> can be used to pipe
<TT
CLASS="FILENAME"
>stdout</TT
> to other commands. This permits
such stunts as <A
HREF="assortedtips.html#PREPENDREF"
>prepending lines
to a file</A
>.</P
><P
>Using <A
HREF="filearchiv.html#DIFFREF"
>diff</A
> to
compare a file with a <EM
>section</EM
>
of another:</P
><P
><TT
CLASS="USERINPUT"
><B
>grep Linux file1 | diff file2 -</B
></TT
></P
><P
>Finally, a real-world example using
<TT
CLASS="REPLACEABLE"
><I
>-</I
></TT
> with <A
HREF="filearchiv.html#TARREF"
>tar</A
>.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="EX58"
></A
><P
><B
>Example 3-4. Backup of all files changed in last day</B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# Backs up all files in current directory modified within last 24 hours
#+ in a "tarball" (tarred and gzipped file).
BACKUPFILE=backup-$(date +%m-%d-%Y)
# Embeds date in backup filename.
# Thanks, Joshua Tschida, for the idea.
archive=${1:-$BACKUPFILE}
# If no backup-archive filename specified on command-line,
#+ it will default to "backup-MM-DD-YYYY.tar.gz."
tar cvf - `find . -mtime -1 -type f -print` &#62; $archive.tar
gzip $archive.tar
echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
# Stephane Chazelas points out that the above code will fail
#+ if there are too many files found
#+ or if any filenames contain blank characters.
# He suggests the following alternatives:
# -------------------------------------------------------------------
# find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
# using the GNU version of "find".
# find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;
# portable to other UNIX flavors, but much slower.
# -------------------------------------------------------------------
exit 0</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/caution.gif"
HSPACE="5"
ALT="Caution"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>Filenames beginning with
<SPAN
CLASS="QUOTE"
>"-"</SPAN
> may cause problems when coupled with the
<SPAN
CLASS="QUOTE"
>"-"</SPAN
> redirection operator. A script should
check for this and add an appropriate prefix to such
filenames, for example <TT
CLASS="FILENAME"
>./-FILENAME</TT
>,
<TT
CLASS="FILENAME"
>$PWD/-FILENAME</TT
>, or
<TT
CLASS="FILENAME"
>$PATHNAME/-FILENAME</TT
>.</P
><P
>If the value of a variable begins with a
<TT
CLASS="REPLACEABLE"
><I
>-</I
></TT
>, this may likewise create
problems.
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>var="-n"
echo $var
# Has the effect of "echo -n", and outputs nothing.</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></TD
></TR
></TABLE
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>-</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>previous working directory. </B
>A <B
CLASS="COMMAND"
>cd -</B
> command changes to the
previous working directory. This uses the
<A
HREF="internalvariables.html#OLDPWD"
>$OLDPWD</A
> <A
HREF="othertypesv.html#ENVREF"
>environmental variable</A
>.</P
></DIV
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="90%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/caution.gif"
HSPACE="5"
ALT="Caution"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>Do not confuse the <SPAN
CLASS="QUOTE"
>"-"</SPAN
> used in this
sense with the <SPAN
CLASS="QUOTE"
>"-"</SPAN
> redirection
operator just discussed. The interpretation of the
<SPAN
CLASS="QUOTE"
>"-"</SPAN
> depends on the context in which it
appears.</P
></TD
></TR
></TABLE
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>-</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Minus. </B
>Minus sign in an <A
HREF="ops.html#AROPS1"
>arithmetic
operation</A
>.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>=</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Equals. </B
><A
HREF="varassignment.html#EQREF"
>Assignment operator</A
>
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>a=28
echo $a # 28</PRE
></FONT
></TD
></TR
></TABLE
></P
></DIV
><P
>In a <A
HREF="comparison-ops.html#EQUALSIGNREF"
>different context</A
>,
the <SPAN
CLASS="QUOTE"
>"<SPAN
CLASS="TOKEN"
>=</SPAN
>"</SPAN
> is a <A
HREF="comparison-ops.html#SCOMPARISON1"
>string comparison</A
>
operator.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>+</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Plus. </B
>Addition <A
HREF="ops.html#AROPS1"
>arithmetic
operator</A
>.</P
></DIV
><P
>In a <A
HREF="x17129.html#PLUSREF"
>different context</A
>,
the <SPAN
CLASS="TOKEN"
>+</SPAN
> is a <A
HREF="regexp.html"
>Regular
Expression</A
> operator.</P
></DD
><DT
><SPAN
CLASS="TOKEN"
>+</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>Option. </B
>Option flag for a command or filter.</P
></DIV
><P
>Certain commands and <A
HREF="internal.html#BUILTINREF"
>builtins</A
> use the
<TT
CLASS="OPTION"
>+</TT
> to enable certain options and the
<TT
CLASS="OPTION"
>-</TT
> to disable them. In <A
HREF="parameter-substitution.html#PARAMSUBREF"
>parameter substitution</A
>,
the <TT
CLASS="OPTION"
>+</TT
> prefixes an <A
HREF="parameter-substitution.html#PARAMALTV"
> alternate value</A
> that a variable expands to.</P
></DD
><DT
><A
NAME="MODULO00"
></A
><SPAN
CLASS="TOKEN"
>%</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="ops.html#MODULOREF"
>modulo</A
>. </B
>Modulo (remainder of a division) <A
HREF="ops.html#AROPS1"
>arithmetic
operation</A
>.</P
></DIV
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>let "z = 5 % 3"
echo $z # 2</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>In a <A
HREF="parameter-substitution.html#PCTPATREF"
>different context</A
>,
the <SPAN
CLASS="TOKEN"
>%</SPAN
> is a <A
HREF="parameter-substitution.html#PSUB2"
>pattern
matching</A
> operator.</P
></DD
><DT
><A
NAME="TILDEREF"
></A
><SPAN
CLASS="TOKEN"
>~</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>home directory [tilde]. </B
>This corresponds to the <A
HREF="internalvariables.html#HOMEDIRREF"
>$HOME</A
> internal variable.
<TT
CLASS="FILENAME"
>~bozo</TT
> is bozo's home directory,
and <B
CLASS="COMMAND"
>ls ~bozo</B
> lists the contents of it.
<SPAN
CLASS="TOKEN"
>~/</SPAN
> is the current user's home directory,
and <B
CLASS="COMMAND"
>ls ~/</B
> lists the contents of it.
<TABLE
BORDER="1"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="SCREEN"
><TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo ~bozo</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/home/bozo</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo ~</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/home/bozo</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo ~/</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/home/bozo/</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo ~:</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/home/bozo:</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo ~nonexistent-user</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>~nonexistent-user</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></DIV
></DD
><DT
><A
NAME="WORKINGDIRREF"
></A
><SPAN
CLASS="TOKEN"
>~+</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>current working directory. </B
>This corresponds to the <A
HREF="internalvariables.html#PWDREF"
>$PWD</A
> internal variable.</P
></DIV
></DD
><DT
><A
NAME="PREVWORKINGDIR"
></A
><SPAN
CLASS="TOKEN"
>~-</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>previous working directory. </B
>This corresponds to the <A
HREF="internalvariables.html#OLDPWD"
>$OLDPWD</A
> internal variable.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>=~</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="bashver3.html#REGEXMATCHREF"
>regular
expression match</A
>. </B
>This operator was introduced with <A
HREF="bashver3.html#BASH3REF"
>version 3</A
> of Bash.</P
></DIV
></DD
><DT
><A
NAME="BEGLINEREF"
></A
><SPAN
CLASS="TOKEN"
>^</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>beginning-of-line. </B
>In a <A
HREF="regexp.html#REGEXREF"
>regular expression</A
>, a
<SPAN
CLASS="QUOTE"
>"^"</SPAN
> addresses the <A
HREF="x17129.html#CARETREF"
>beginning of a line</A
> of text.</P
></DIV
></DD
><DT
><SPAN
CLASS="TOKEN"
>^</SPAN
>, <SPAN
CLASS="TOKEN"
>^^</SPAN
></DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
><A
HREF="bashver4.html#CASEMODPARAMSUB"
>Uppercase
conversion</A
> in <I
CLASS="FIRSTTERM"
>parameter substitution</I
>
(added in <A
HREF="bashver4.html#BASH4REF"
>version 4</A
> of Bash). </B
></P
></DIV
></DD
><DT
><A
NAME="CONTROLCHARREF"
></A
>Control Characters</DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
> change the behavior of the
terminal or text display. </B
>A control character is a <B
CLASS="KEYCAP"
>CONTROL</B
>
+ <B
CLASS="KEYCAP"
>key</B
> combination (pressed
simultaneously).
A control character may also
be written in <I
CLASS="FIRSTTERM"
>octal</I
> or
<I
CLASS="FIRSTTERM"
>hexadecimal</I
> notation,
following an <I
CLASS="FIRSTTERM"
>escape</I
>.</P
></DIV
><P
>Control characters are not normally useful inside a
script.</P
><P
></P
><UL
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-A</B
></TT
></P
><P
>Moves cursor to beginning of line of text
(on the command-line).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-B</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Backspace</B
></TT
>
(nondestructive).</P
></LI
><LI
><P
><A
NAME="CTLCREF"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-C</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Break</B
></TT
>.
Terminate a foreground job.</P
></LI
><LI
><P
><A
NAME="CTLDREF"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-D</B
></TT
></P
><P
><I
CLASS="FIRSTTERM"
>Log out</I
> from a shell (similar to
<A
HREF="exit-status.html#EXITCOMMANDREF"
>exit</A
>).</P
><P
><TT
CLASS="USERINPUT"
><B
>EOF</B
></TT
> (end-of-file). This also
terminates input from <TT
CLASS="FILENAME"
>stdin</TT
>.</P
><P
>When typing text on the console or in an
<I
CLASS="FIRSTTERM"
>xterm</I
> window,
<TT
CLASS="USERINPUT"
><B
>Ctl-D</B
></TT
> erases the character under the
cursor. When there are no characters present,
<TT
CLASS="USERINPUT"
><B
>Ctl-D</B
></TT
> logs out of the session, as
expected. In an <I
CLASS="FIRSTTERM"
>xterm</I
> window,
this has the effect of closing the window.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-E</B
></TT
></P
><P
>Moves cursor to end of line of text
(on the command-line).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-F</B
></TT
></P
><P
>Moves cursor forward one character position
(on the command-line).</P
></LI
><LI
><P
><A
NAME="CTLGREF"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-G</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>BEL</B
></TT
>. On some
old-time teletype terminals, this would actually ring
a bell. In an <I
CLASS="FIRSTTERM"
>xterm</I
> it might
beep.</P
></LI
><LI
><P
><A
NAME="CTLHREF"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-H</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Rubout</B
></TT
> (destructive backspace).
Erases characters the cursor backs over while
backspacing.</P
><P
> <TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# Embedding Ctl-H in a string.
a="^H^H" # Two Ctl-H's -- backspaces
# ctl-V ctl-H, using vi/vim
echo "abcdef" # abcdef
echo
echo -n "abcdef$a " # abcd f
# Space at end ^ ^ Backspaces twice.
echo
echo -n "abcdef$a" # abcdef
# No space at end ^ Doesn't backspace (why?).
# Results may not be quite as expected.
echo; echo
# Constantin Hagemeier suggests trying:
# a=$'\010\010'
# a=$'\b\b'
# a=$'\x08\x08'
# But, this does not change the results.
########################################
# Now, try this.
rubout="^H^H^H^H^H" # 5 x Ctl-H.
echo -n "12345678"
sleep 2
echo -n "$rubout"
sleep 2</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-I</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Horizontal tab</B
></TT
>.</P
></LI
><LI
><P
><A
NAME="CTLJREF"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-J</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Newline</B
></TT
> (line feed).
In a script, may also be expressed in octal notation --
'\012' or in hexadecimal -- '\x0a'.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-K</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Vertical tab</B
></TT
>.</P
><P
>When typing text on the console or in an
<I
CLASS="FIRSTTERM"
>xterm</I
> window,
<TT
CLASS="USERINPUT"
><B
>Ctl-K</B
></TT
> erases from the character
under the cursor to end of line. Within a script,
<TT
CLASS="USERINPUT"
><B
>Ctl-K</B
></TT
> may behave differently,
as in Lee Lee Maschmeyer's example, below.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-L</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Formfeed</B
></TT
> (clear the terminal
screen). In a terminal, this has the same effect as the
<A
HREF="terminalccmds.html#CLEARREF"
>clear</A
> command. When sent
to a printer, a <TT
CLASS="USERINPUT"
><B
>Ctl-L</B
></TT
> causes
an advance to end of the paper sheet.</P
></LI
><LI
><P
><A
NAME="CTLMREF"
></A
></P
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-M</B
></TT
></P
><P
><TT
CLASS="USERINPUT"
><B
>Carriage return</B
></TT
>.</P
><P
> <TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
# Thank you, Lee Maschmeyer, for this example.
read -n 1 -s -p \
$'Control-M leaves cursor at beginning of this line. Press Enter. \x0d'
# Of course, '0d' is the hex equivalent of Control-M.
echo &#62;&#38;2 # The '-s' makes anything typed silent,
#+ so it is necessary to go to new line explicitly.
read -n 1 -s -p $'Control-J leaves cursor on next line. \x0a'
# '0a' is the hex equivalent of Control-J, linefeed.
echo &#62;&#38;2
###
read -n 1 -s -p $'And Control-K\x0bgoes straight down.'
echo &#62;&#38;2 # Control-K is vertical tab.
# A better example of the effect of a vertical tab is:
var=$'\x0aThis is the bottom line\x0bThis is the top line\x0a'
echo "$var"
# This works the same way as the above example. However:
echo "$var" | col
# This causes the right end of the line to be higher than the left end.
# It also explains why we started and ended with a line feed --
#+ to avoid a garbled screen.
# As Lee Maschmeyer explains:
# --------------------------
# In the [first vertical tab example] . . . the vertical tab
#+ makes the printing go straight down without a carriage return.
# This is true only on devices, such as the Linux console,
#+ that can't go "backward."
# The real purpose of VT is to go straight UP, not down.
# It can be used to print superscripts on a printer.
# The col utility can be used to emulate the proper behavior of VT.
exit 0</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-N</B
></TT
></P
><P
>Erases a line of text recalled from
<I
CLASS="FIRSTTERM"
>history buffer</I
>
<A
NAME="AEN2107"
HREF="#FTN.AEN2107"
><SPAN
CLASS="footnote"
>[8]</SPAN
></A
> (on the
command-line).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-O</B
></TT
></P
><P
>Issues a <I
CLASS="FIRSTTERM"
>newline</I
>
(on the command-line).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-P</B
></TT
></P
><P
>Recalls last command from <I
CLASS="FIRSTTERM"
>history
buffer</I
> (on the command-line).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-Q</B
></TT
></P
><P
>Resume (<TT
CLASS="USERINPUT"
><B
>XON</B
></TT
>).</P
><P
>This resumes <TT
CLASS="FILENAME"
>stdin</TT
> in a terminal.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-R</B
></TT
></P
><P
>Backwards search for text in <I
CLASS="FIRSTTERM"
>history
buffer</I
>
(on the command-line).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-S</B
></TT
></P
><P
>Suspend (<TT
CLASS="USERINPUT"
><B
>XOFF</B
></TT
>).</P
><P
>This freezes <TT
CLASS="FILENAME"
>stdin</TT
> in a terminal.
(Use Ctl-Q to restore input.)</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-T</B
></TT
></P
><P
>Reverses the position of the character the cursor
is on with the previous character (on the
command-line).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-U</B
></TT
></P
><P
>Erase a line of input, from the cursor backward to
beginning of line. In some settings,
<TT
CLASS="USERINPUT"
><B
>Ctl-U</B
></TT
> erases the entire
line of input, <EM
>regardless of cursor
position</EM
>.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-V</B
></TT
></P
><P
>When inputting text, <TT
CLASS="USERINPUT"
><B
>Ctl-V</B
></TT
>
permits inserting control characters. For example, the
following two are equivalent:
<TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>echo -e '\x0a'
echo &#60;Ctl-V&#62;&#60;Ctl-J&#62;</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-V</B
></TT
> is primarily useful from
within a text editor.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-W</B
></TT
></P
><P
>When typing text on the console or in an xterm window,
<TT
CLASS="USERINPUT"
><B
>Ctl-W</B
></TT
> erases from the character
under the cursor backwards to the first instance of
<A
HREF="special-chars.html#WHITESPACEREF"
>whitespace</A
>. In
some settings, <TT
CLASS="USERINPUT"
><B
>Ctl-W</B
></TT
> erases
backwards to first non-alphanumeric character.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-X</B
></TT
></P
><P
>In certain word processing programs,
<I
CLASS="FIRSTTERM"
>Cuts</I
> highlighted text
and copies to <I
CLASS="FIRSTTERM"
>clipboard</I
>.</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-Y</B
></TT
></P
><P
><I
CLASS="FIRSTTERM"
>Pastes</I
> back text previously
erased (with <TT
CLASS="USERINPUT"
><B
>Ctl-U</B
></TT
> or
<TT
CLASS="USERINPUT"
><B
>Ctl-W</B
></TT
>).</P
></LI
><LI
><P
><TT
CLASS="USERINPUT"
><B
>Ctl-Z</B
></TT
></P
><P
><I
CLASS="FIRSTTERM"
>Pauses</I
> a foreground job.</P
><P
><I
CLASS="FIRSTTERM"
>Substitute</I
> operation in certain
word processing applications.</P
><P
><TT
CLASS="USERINPUT"
><B
>EOF</B
></TT
> (end-of-file) character
in the MSDOS filesystem.</P
></LI
></UL
></DD
><DT
><A
NAME="WHITESPACEREF"
></A
>Whitespace</DT
><DD
><DIV
CLASS="FORMALPARA"
><P
><B
>functions as a separator between commands and/or
variables. </B
>Whitespace consists of either
<I
CLASS="FIRSTTERM"
>spaces</I
>,
<I
CLASS="FIRSTTERM"
>tabs</I
>, <I
CLASS="FIRSTTERM"
>blank
lines</I
>, or any combination thereof.
<A
NAME="AEN2198"
HREF="#FTN.AEN2198"
><SPAN
CLASS="footnote"
>[9]</SPAN
></A
>
In some contexts, such as <A
HREF="gotchas.html#WSBAD"
>variable
assignment</A
>, whitespace is not permitted, and
results in a syntax error.</P
></DIV
><P
>Blank lines have no effect on the action of a script,
and are therefore useful for visually separating functional
sections.</P
><P
><A
HREF="internalvariables.html#IFSREF"
>$IFS</A
>, the special variable
separating <I
CLASS="FIRSTTERM"
>fields</I
> of input to certain
commands. It defaults to whitespace.</P
><TABLE
CLASS="SIDEBAR"
BORDER="1"
CELLPADDING="5"
><TR
><TD
><DIV
CLASS="SIDEBAR"
><A
NAME="AEN2207"
></A
><P
></P
><P
> <A
NAME="FIELDREF"
></A
><TT
CLASS="USERINPUT"
><B
>Definition:</B
></TT
>
A <I
CLASS="FIRSTTERM"
>field</I
> is a discrete chunk of data
expressed as a string of consecutive characters.
Separating each field from adjacent fields is either
<I
CLASS="FIRSTTERM"
>whitespace</I
> or some other designated
character (often determined by the <SPAN
CLASS="TOKEN"
>$IFS</SPAN
>).
In some contexts, a field may be called a
<I
CLASS="FIRSTTERM"
>record</I
>.
</P
><P
></P
></DIV
></TD
></TR
></TABLE
><P
><A
NAME="QUOTINGWS"
></A
></P
><P
>To preserve <I
CLASS="FIRSTTERM"
>whitespace</I
>
within a string or in a variable, use <A
HREF="quoting.html#QUOTINGREF"
>quoting</A
>.</P
><P
>UNIX <A
HREF="special-chars.html#FILTERDEF"
>filters</A
>
can target and operate on <I
CLASS="FIRSTTERM"
>whitespace</I
>
using the <A
HREF="x17129.html#POSIXREF"
>POSIX</A
> character class
<A
HREF="x17129.html#WSPOSIX"
>[:space:]</A
>.</P
></DD
></DL
></DIV
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN612"
HREF="special-chars.html#AEN612"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
><A
NAME="OPERATORDEF"
></A
>An
<I
CLASS="FIRSTTERM"
>operator</I
> is an agent that carries
out an <I
CLASS="FIRSTTERM"
>operation</I
>. Some examples
are the common <A
HREF="ops.html#AROPS1"
>arithmetic
operators</A
>, <B
CLASS="COMMAND"
>+ - * /</B
>. In
Bash, there is some overlap between the concepts
of <I
CLASS="FIRSTTERM"
>operator</I
> and <A
HREF="internal.html#KEYWORDREF"
>keyword</A
>.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN888"
HREF="special-chars.html#AEN888"
><SPAN
CLASS="footnote"
>[2]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>This is more commonly known
as the <I
CLASS="FIRSTTERM"
>ternary</I
>
operator. Unfortunately, <I
CLASS="FIRSTTERM"
>ternary</I
>
is an ugly word. It doesn't roll off
the tongue, and it doesn't elucidate. It
obfuscates. <I
CLASS="FIRSTTERM"
>Trinary</I
> is by far
the more elegant usage.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN1001"
HREF="special-chars.html#AEN1001"
><SPAN
CLASS="footnote"
>[3]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
><A
NAME="ASCIIDEF"
></A
></P
><P
><B
CLASS="COMMAND"
>A</B
>merican
<B
CLASS="COMMAND"
>S</B
>tandard
<B
CLASS="COMMAND"
>C</B
>ode
for
<B
CLASS="COMMAND"
>I</B
>nformation
<B
CLASS="COMMAND"
>I</B
>nterchange.
This is a system for encoding text characters
(alphabetic, numeric, and a limited set of symbols)
as 7-bit numbers that can be stored and manipulated by
computers. Many of the ASCII characters are
represented on a standard keyboard.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN1071"
HREF="special-chars.html#AEN1071"
><SPAN
CLASS="footnote"
>[4]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
><A
NAME="PROCESSIDDEF"
></A
></P
><P
>A <I
CLASS="FIRSTTERM"
>PID</I
>, or
<I
CLASS="FIRSTTERM"
>process ID</I
>, is a number assigned
to a running process. The <I
CLASS="FIRSTTERM"
>PID</I
>s
of running processes may be viewed with a <A
HREF="system.html#PPSSREF"
>ps</A
> command.
</P
><P
><A
NAME="PROCESSREF"
></A
></P
><P
> <TT
CLASS="USERINPUT"
><B
>Definition:</B
></TT
> A
<I
CLASS="FIRSTTERM"
>process</I
> is a currently
executing command (or program), sometimes referred
to as a <I
CLASS="FIRSTTERM"
>job</I
>. </P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN1124"
HREF="special-chars.html#AEN1124"
><SPAN
CLASS="footnote"
>[5]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>The shell does the <I
CLASS="FIRSTTERM"
>brace
expansion</I
>. The command itself acts upon the
<EM
>result</EM
> of the expansion.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN1199"
HREF="special-chars.html#AEN1199"
><SPAN
CLASS="footnote"
>[6]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>Exception: a code block in braces as
part of a pipe <EM
>may</EM
> run as a
<A
HREF="subshells.html#SUBSHELLSREF"
>subshell</A
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>ls | { read firstline; read secondline; }
# Error. The code block in braces runs as a subshell,
#+ so the output of "ls" cannot be passed to variables within the block.
echo "First line is $firstline; second line is $secondline" # Won't work.
# Thanks, S.C.</PRE
></FONT
></TD
></TR
></TABLE
></P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN1564"
HREF="special-chars.html#AEN1564"
><SPAN
CLASS="footnote"
>[7]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
> Even as in olden times a
<I
CLASS="FIRSTTERM"
>philtre</I
> denoted a potion alleged
to have magical transformative powers, so does a UNIX
<I
CLASS="FIRSTTERM"
>filter</I
> transform its target in
(roughly) analogous fashion. (The coder who comes up with a
<SPAN
CLASS="QUOTE"
>"love philtre"</SPAN
> that runs on a Linux machine
will likely win accolades and honors.)</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN2107"
HREF="special-chars.html#AEN2107"
><SPAN
CLASS="footnote"
>[8]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>Bash stores a list of commands
previously issued from the command-line
in a <I
CLASS="FIRSTTERM"
>buffer</I
>, or
memory space, for recall with the <A
HREF="internal.html#BUILTINREF"
>builtin</A
>
<I
CLASS="FIRSTTERM"
>history</I
>
commands.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN2198"
HREF="special-chars.html#AEN2198"
><SPAN
CLASS="footnote"
>[9]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>A linefeed (<I
CLASS="FIRSTTERM"
>newline</I
>)
is also a whitespace character. This explains
why a <I
CLASS="FIRSTTERM"
>blank line</I
>,
consisting only of a linefeed, is considered
whitespace.</P
></TD
></TR
></TABLE
><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="part2.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="variables.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Basics</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="part2.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Introduction to Variables and Parameters</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>