old-www/LDP/abs/html/bashver3.html

750 lines
11 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>Bash, version 3</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="Bash, versions 2, 3, and 4"
HREF="bash2.html"><LINK
REL="PREVIOUS"
TITLE="Bash, version 2"
HREF="bashver2.html"><LINK
REL="NEXT"
TITLE="Bash, version 4"
HREF="bashver4.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"
>Advanced Bash-Scripting Guide: </TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="bashver2.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 37. Bash, versions 2, 3, and 4</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="bashver4.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="BASHVER3"
></A
>37.2. Bash, version 3</H1
><P
><A
NAME="BASH3REF"
></A
></P
><P
>On July 27, 2004, Chet Ramey released version 3 of Bash.
This update fixed quite a number of bugs and added new
features.</P
><P
>Some of the more important added features:
<P
></P
><UL
><LI
><P
><A
NAME="BRACEEXPREF3"
></A
></P
><P
>A new, more generalized <B
CLASS="COMMAND"
>{a..z}</B
> <A
HREF="special-chars.html#BRACEEXPREF"
>brace expansion</A
> operator.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
for i in {1..10}
# Simpler and more straightforward than
#+ for i in $(seq 10)
do
echo -n "$i "
done
echo
# 1 2 3 4 5 6 7 8 9 10
# Or just . . .
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
echo {e..m} # e f g h i j k l m
echo {z..a} # z y x w v u t s r q p o n m l k j i h g f e d c b a
# Works backwards, too.
echo {25..30} # 25 26 27 28 29 30
echo {3..-2} # 3 2 1 0 -1 -2
echo {X..d} # X Y Z [ ] ^ _ ` a b c d
# Shows (some of) the ASCII characters between Z and a,
#+ but don't rely on this type of behavior because . . .
echo {]..a} # {]..a}
# Why?
# You can tack on prefixes and suffixes.
echo "Number #"{1..4}, "..."
# Number #1, Number #2, Number #3, Number #4, ...
# You can concatenate brace-expansion sets.
echo {1..3}{x..z}" +" "..."
# 1x + 1y + 1z + 2x + 2y + 2z + 3x + 3y + 3z + ...
# Generates an algebraic expression.
# This could be used to find permutations.
# You can nest brace-expansion sets.
echo {{a..c},{1..3}}
# a b c 1 2 3
# The "comma operator" splices together strings.
# ########## ######### ############ ########### ######### ###############
# Unfortunately, brace expansion does not lend itself to parameterization.
var1=1
var2=5
echo {$var1..$var2} # {1..5}
# Yet, as Emiliano G. points out, using "eval" overcomes this limitation.
start=0
end=10
for index in $(eval echo {$start..$end})
do
echo -n "$index " # 0 1 2 3 4 5 6 7 8 9 10
done
echo</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
><LI
><P
>The <B
CLASS="COMMAND"
>${!array[@]}</B
> operator, which
expands to all the indices of a given <A
HREF="arrays.html#ARRAYREF"
>array</A
>.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
Array=(element-zero element-one element-two element-three)
echo ${Array[0]} # element-zero
# First element of array.
echo ${!Array[@]} # 0 1 2 3
# All the indices of Array.
for i in ${!Array[@]}
do
echo ${Array[i]} # element-zero
# element-one
# element-two
# element-three
#
# All the elements in Array.
done</PRE
></FONT
></TD
></TR
></TABLE
></P
></LI
><LI
><P
><A
NAME="REGEXMATCHREF"
></A
></P
><P
>The <B
CLASS="COMMAND"
>=~</B
> <A
HREF="regexp.html#REGEXREF"
>Regular
Expression</A
> matching operator within a <A
HREF="testconstructs.html#DBLBRACKETS"
>double brackets</A
> test expression.
(Perl has a similar operator.)</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
variable="This is a fine mess."
echo "$variable"
# Regex matching with =~ operator within [[ double brackets ]].
if [[ "$variable" =~ T.........fin*es* ]]
# NOTE: As of version 3.2 of Bash, expression to match no longer quoted.
then
echo "match found"
# match found
fi</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>Or, more usefully:</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>#!/bin/bash
input=$1
if [[ "$input" =~ "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" ]]
# ^ NOTE: Quoting not necessary, as of version 3.2 of Bash.
# NNN-NN-NNNN (where each N is a digit).
then
echo "Social Security number."
# Process SSN.
else
echo "Not a Social Security number!"
# Or, ask for corrected input.
fi</PRE
></FONT
></TD
></TR
></TABLE
></P
><P
>For additional examples of using the
<B
CLASS="COMMAND"
>=~</B
> operator, see <A
HREF="contributed-scripts.html#WHX"
>Example A-29</A
>,
<A
HREF="x17837.html#MAILBOXGREP"
>Example 19-14</A
>, <A
HREF="contributed-scripts.html#FINDSPLIT"
>Example A-35</A
>, and <A
HREF="contributed-scripts.html#TOHTML"
>Example A-24</A
>.</P
></LI
><LI
><P
><A
NAME="PIPEFAILREF"
></A
></P
><P
>The new <TT
CLASS="OPTION"
>set -o pipefail</TT
> option is
useful for debugging <A
HREF="special-chars.html#PIPEREF"
>pipes</A
>. If
this option is set, then the <A
HREF="exit-status.html#EXITSTATUSREF"
>exit status</A
> of a pipe
is the exit status of the last command in the pipe to
<EM
>fail</EM
> (return a non-zero value), rather
than the actual final command in the pipe.</P
><P
>See <A
HREF="communications.html#FC4UPD"
>Example 16-43</A
>.</P
></LI
></UL
>
</P
><DIV
CLASS="CAUTION"
><P
></P
><TABLE
CLASS="CAUTION"
WIDTH="100%"
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
>The update to version 3 of Bash breaks a few scripts
that worked under earlier versions. <EM
>Test critical legacy
scripts to make sure they still work!</EM
></P
><P
>As it happens, a couple of the scripts in the
<EM
>Advanced Bash Scripting Guide</EM
> had to be
fixed up (see <A
HREF="internalvariables.html#TOUT"
>Example 9-4</A
>, for instance).</P
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN20956"
></A
>37.2.1. Bash, version 3.1</H2
><P
>The version 3.1 update of Bash introduces a number of bugfixes
and a few minor changes.</P
><P
></P
><UL
><LI
><P
>The <SPAN
CLASS="TOKEN"
>+=</SPAN
> operator is now permitted in
in places where previously only the <SPAN
CLASS="TOKEN"
>=</SPAN
>
assignment operator was recognized.</P
><P
><A
NAME="PLUSEQSTR"
></A
></P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>a=1
echo $a # 1
a+=5 # Won't work under versions of Bash earlier than 3.1.
echo $a # 15
a+=Hello
echo $a # 15Hello</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
>Here, <SPAN
CLASS="TOKEN"
>+=</SPAN
> functions as a <I
CLASS="FIRSTTERM"
>string
concatenation</I
> operator. Note that its behavior
in this particular context is different than within a
<A
HREF="internal.html#LETREF"
>let</A
> construct.</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="90%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
>a=1
echo $a # 1
let a+=5 # Integer arithmetic, rather than string concatenation.
echo $a # 6
let a+=Hello # Doesn't "add" anything to a.
echo $a # 6</PRE
></FONT
></TD
></TR
></TABLE
>
</P
><P
><A
NAME="PATHAPPEND"
></A
>Jeffrey Haemer points out
that this concatenation operator can be quite
useful. In this instance, we append a directory to the
<TT
CLASS="VARNAME"
>$PATH</TT
>.</P
><P
>&#13; <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/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games</TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>PATH+=:/opt/bin</B
></TT
>
<TT
CLASS="PROMPT"
>bash$ </TT
><TT
CLASS="USERINPUT"
><B
>echo $PATH</B
></TT
>
<TT
CLASS="COMPUTEROUTPUT"
>/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games:/opt/bin</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
>
</P
></LI
></UL
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN20987"
></A
>37.2.2. Bash, version 3.2</H2
><P
>This is pretty much a bugfix update.</P
><P
></P
><UL
><LI
><P
>In <A
HREF="parameter-substitution.html#PSGLOB"
><I
CLASS="FIRSTTERM"
>global</I
>
parameter substitutions</A
>, the pattern no longer anchors
at the start of the string.</P
></LI
><LI
><P
>The <TT
CLASS="OPTION"
>--wordexp</TT
> option disables
<A
HREF="process-sub.html#PROCESSSUBREF"
>process substitution</A
>.</P
></LI
><LI
><P
>The <B
CLASS="COMMAND"
>=~</B
> <A
HREF="bashver3.html#REGEXMATCHREF"
>Regular Expression
match operator</A
> no longer requires
<A
HREF="quoting.html#QUOTINGREF"
>quoting</A
> of the
<I
CLASS="FIRSTTERM"
>pattern</I
> within <A
HREF="testconstructs.html#DBLBRACKETS"
>[[ ... ]]</A
>.</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
>In fact, quoting in this context is
<EM
>not</EM
> advisable as it may
cause <I
CLASS="FIRSTTERM"
>regex</I
> evaluation to fail.
Chet Ramey states in the <A
HREF="biblio.html#BASHFAQ"
>Bash
FAQ</A
> that quoting explicitly disables regex evaluation.
See also the <A
HREF="https://bugs.launchpad.net/ubuntu-website/+bug/109931"
TARGET="_top"
> Ubuntu Bug List</A
> and <A
HREF="http://en.wikinerds.org/index.php/Bash_syntax_and_semantics"
TARGET="_top"
> Wikinerds on Bash syntax</A
>.</P
><P
>Setting <EM
>shopt -s compat31</EM
>
in a script causes reversion to the original
behavior.</P
></TD
></TR
></TABLE
></DIV
></LI
></UL
></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="bashver2.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="bashver4.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Bash, version 2</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="bash2.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Bash, version 4</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>