Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

34.2. Bash, version 3

On July 27, 2004, Chet Ramey released version 3 of Bash. This update fixed quite a number of bugs and added new features.

Some of the more important added features:

  • A new, more generalized {a..z} brace expansion operator.

    #!/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 {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 {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?
    
    
    
    # Unfortunately, this does not lend itself to parameterization.
    var1=1
    var2=5
    echo {$var1..$var2}   # {1..5}
  • The ${!array[@]} operator, which expands to all the indices of a given array.

    #!/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
  • The =~ Regular Expression matching operator within a double brackets test expression. (Perl has a similar operator.)

    #!/bin/bash
    
    variable="This is a fine mess."
    
    echo "$variable"
    
    # Regex matching with =~ operator within [[ double brackets ]].
    if [[ "$variable" =~ "T.........fin*es*" ]]
    #                    ^                 ^
    # NOTE: Quoting not necessary, as of version 3.2 of Bash.
    then
      echo "match found"
          # match found
    fi

    Or, more usefully:

    #!/bin/bash
    
    input=$1
    
    
    if [[ "$input" =~ "[1-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). Initial digit must not be 0.
    then
      echo "Social Security number."
      # Process SSN.
    else
      echo "Not a Social Security number!"
      # Or, ask for corrected input.
    fi

    For additional examples of using the =~ operator, see Example A-31, Example 18-14, Example A-37, and Example A-26.

  • The new set -o pipefail option is useful for debugging pipes. If this option is set, then the exit status of a pipe is the exit status of the last command in the pipe to fail (return a non-zero value), rather than the actual final command in the pipe.

    See Example 15-43.

The update to version 3 of Bash breaks a few scripts that worked under earlier versions. Test critical legacy scripts to make sure they still work!

As it happens, a couple of the scripts in the Advanced Bash Scripting Guide had to be fixed up (see Example A-21 and Example 9-4, for instance).

34.2.1. Bash, version 3.1

The version 3.1 update of Bash introduces a number of bugfixes and a few minor changes.

  • The += operator is now permitted in in places where previously only the = assignment operator was recognized.

    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

    Here, += functions as a string concatenation operator. Note that its behavior in this particular context is different than within a let construct.

    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

34.2.2. Bash, version 3.2

This is pretty much a bugfix update.