bash: Conditional Constructs
1
1 3.2.4.2 Conditional Constructs
1 ..............................
1
1 'if'
1 The syntax of the 'if' command is:
1
1 if TEST-COMMANDS; then
1 CONSEQUENT-COMMANDS;
1 [elif MORE-TEST-COMMANDS; then
1 MORE-CONSEQUENTS;]
1 [else ALTERNATE-CONSEQUENTS;]
1 fi
1
1 The TEST-COMMANDS list is executed, and if its return status is
1 zero, the CONSEQUENT-COMMANDS list is executed. If TEST-COMMANDS
1 returns a non-zero status, each 'elif' list is executed in turn,
1 and if its exit status is zero, the corresponding MORE-CONSEQUENTS
1 is executed and the command completes. If 'else
1 ALTERNATE-CONSEQUENTS' is present, and the final command in the
1 final 'if' or 'elif' clause has a non-zero exit status, then
1 ALTERNATE-CONSEQUENTS is executed. The return status is the exit
1 status of the last command executed, or zero if no condition tested
1 true.
1
1 'case'
1 The syntax of the 'case' command is:
1
1 case WORD in [ [(] PATTERN [| PATTERN]...) COMMAND-LIST ;;]... esac
1
1 'case' will selectively execute the COMMAND-LIST corresponding to
1 the first PATTERN that matches WORD. If the 'nocasematch' shell
11 option (see the description of 'shopt' in ⇒The Shopt
Builtin) is enabled, the match is performed without regard to the
1 case of alphabetic characters. The '|' is used to separate
1 multiple patterns, and the ')' operator terminates a pattern list.
1 A list of patterns and an associated command-list is known as a
1 CLAUSE.
1
1 Each clause must be terminated with ';;', ';&', or ';;&'. The WORD
1 undergoes tilde expansion, parameter expansion, command
1 substitution, arithmetic expansion, and quote removal before
1 matching is attempted. Each PATTERN undergoes tilde expansion,
1 parameter expansion, command substitution, and arithmetic
1 expansion.
1
1 There may be an arbitrary number of 'case' clauses, each terminated
1 by a ';;', ';&', or ';;&'. The first pattern that matches
1 determines the command-list that is executed. It's a common idiom
1 to use '*' as the final pattern to define the default case, since
1 that pattern will always match.
1
1 Here is an example using 'case' in a script that could be used to
1 describe one interesting feature of an animal:
1
1 echo -n "Enter the name of an animal: "
1 read ANIMAL
1 echo -n "The $ANIMAL has "
1 case $ANIMAL in
1 horse | dog | cat) echo -n "four";;
1 man | kangaroo ) echo -n "two";;
1 *) echo -n "an unknown number of";;
1 esac
1 echo " legs."
1
1
1 If the ';;' operator is used, no subsequent matches are attempted
1 after the first pattern match. Using ';&' in place of ';;' causes
1 execution to continue with the COMMAND-LIST associated with the
1 next clause, if any. Using ';;&' in place of ';;' causes the shell
1 to test the patterns in the next clause, if any, and execute any
1 associated COMMAND-LIST on a successful match.
1
1 The return status is zero if no PATTERN is matched. Otherwise, the
1 return status is the exit status of the COMMAND-LIST executed.
1
1 'select'
1
1 The 'select' construct allows the easy generation of menus. It has
1 almost the same syntax as the 'for' command:
1
1 select NAME [in WORDS ...]; do COMMANDS; done
1
1 The list of words following 'in' is expanded, generating a list of
1 items. The set of expanded words is printed on the standard error
1 output stream, each preceded by a number. If the 'in WORDS' is
1 omitted, the positional parameters are printed, as if 'in "$@"' had
1 been specified. The 'PS3' prompt is then displayed and a line is
1 read from the standard input. If the line consists of a number
1 corresponding to one of the displayed words, then the value of NAME
1 is set to that word. If the line is empty, the words and prompt
1 are displayed again. If 'EOF' is read, the 'select' command
1 completes. Any other value read causes NAME to be set to null.
1 The line read is saved in the variable 'REPLY'.
1
1 The COMMANDS are executed after each selection until a 'break'
1 command is executed, at which point the 'select' command completes.
1
1 Here is an example that allows the user to pick a filename from the
1 current directory, and displays the name and index of the file
1 selected.
1
1 select fname in *;
1 do
1 echo you picked $fname \($REPLY\)
1 break;
1 done
1
1 '((...))'
1 (( EXPRESSION ))
1
1 The arithmetic EXPRESSION is evaluated according to the rules
1 described below (⇒Shell Arithmetic). If the value of the
1 expression is non-zero, the return status is 0; otherwise the
1 return status is 1. This is exactly equivalent to
1 let "EXPRESSION"
1 ⇒Bash Builtins, for a full description of the 'let' builtin.
1
1 '[[...]]'
1 [[ EXPRESSION ]]
1
1 Return a status of 0 or 1 depending on the evaluation of the
1 conditional expression EXPRESSION. Expressions are composed of the
1 primaries described below in ⇒Bash Conditional Expressions.
1 Word splitting and filename expansion are not performed on the
1 words between the '[[' and ']]'; tilde expansion, parameter and
1 variable expansion, arithmetic expansion, command substitution,
1 process substitution, and quote removal are performed. Conditional
1 operators such as '-f' must be unquoted to be recognized as
1 primaries.
1
1 When used with '[[', the '<' and '>' operators sort
1 lexicographically using the current locale.
1
1 When the '==' and '!=' operators are used, the string to the right
1 of the operator is considered a pattern and matched according to
1 the rules described below in ⇒Pattern Matching, as if the
1 'extglob' shell option were enabled. The '=' operator is identical
1 to '=='. If the 'nocasematch' shell option (see the description of
1 'shopt' in ⇒The Shopt Builtin) is enabled, the match is
1 performed without regard to the case of alphabetic characters. The
1 return value is 0 if the string matches ('==') or does not match
1 ('!=')the pattern, and 1 otherwise. Any part of the pattern may be
1 quoted to force the quoted portion to be matched as a string.
1
1 An additional binary operator, '=~', is available, with the same
1 precedence as '==' and '!='. When it is used, the string to the
1 right of the operator is considered an extended regular expression
1 and matched accordingly (as in regex3)). The return value is 0 if
1 the string matches the pattern, and 1 otherwise. If the regular
1 expression is syntactically incorrect, the conditional expression's
1 return value is 2. If the 'nocasematch' shell option (see the
1 description of 'shopt' in ⇒The Shopt Builtin) is enabled,
1 the match is performed without regard to the case of alphabetic
1 characters. Any part of the pattern may be quoted to force the
1 quoted portion to be matched as a string. Bracket expressions in
1 regular expressions must be treated carefully, since normal quoting
1 characters lose their meanings between brackets. If the pattern is
1 stored in a shell variable, quoting the variable expansion forces
1 the entire pattern to be matched as a string. Substrings matched
1 by parenthesized subexpressions within the regular expression are
1 saved in the array variable 'BASH_REMATCH'. The element of
1 'BASH_REMATCH' with index 0 is the portion of the string matching
1 the entire regular expression. The element of 'BASH_REMATCH' with
1 index N is the portion of the string matching the Nth parenthesized
1 subexpression.
1
1 For example, the following will match a line (stored in the shell
1 variable LINE) if there is a sequence of characters in the value
1 consisting of any number, including zero, of space characters, zero
1 or one instances of 'a', then a 'b':
1 [[ $line =~ [[:space:]]*(a)?b ]]
1
1 That means values like 'aab' and ' aaaaaab' will match, as will a
1 line containing a 'b' anywhere in its value.
1
1 Storing the regular expression in a shell variable is often a
1 useful way to avoid problems with quoting characters that are
1 special to the shell. It is sometimes difficult to specify a
1 regular expression literally without using quotes, or to keep track
1 of the quoting used by regular expressions while paying attention
1 to the shell's quote removal. Using a shell variable to store the
1 pattern decreases these problems. For example, the following is
1 equivalent to the above:
1 pattern='[[:space:]]*(a)?b'
1 [[ $line =~ $pattern ]]
1
1 If you want to match a character that's special to the regular
1 expression grammar, it has to be quoted to remove its special
1 meaning. This means that in the pattern 'xxx.txt', the '.' matches
1 any character in the string (its usual regular expression meaning),
1 but in the pattern '"xxx.txt"' it can only match a literal '.'.
1 Shell programmers should take special care with backslashes, since
1 backslashes are used both by the shell and regular expressions to
1 remove the special meaning from the following character. The
1 following two sets of commands are _not_ equivalent:
1 pattern='\.'
1
1 [[ . =~ $pattern ]]
1 [[ . =~ \. ]]
1
1 [[ . =~ "$pattern" ]]
1 [[ . =~ '\.' ]]
1
1 The first two matches will succeed, but the second two will not,
1 because in the second two the backslash will be part of the pattern
1 to be matched. In the first two examples, the backslash removes
1 the special meaning from '.', so the literal '.' matches. If the
1 string in the first examples were anything other than '.', say 'a',
1 the pattern would not match, because the quoted '.' in the pattern
1 loses its special meaning of matching any single character.
1
1 Expressions may be combined using the following operators, listed
1 in decreasing order of precedence:
1
1 '( EXPRESSION )'
1 Returns the value of EXPRESSION. This may be used to override
1 the normal precedence of operators.
1
1 '! EXPRESSION'
1 True if EXPRESSION is false.
1
1 'EXPRESSION1 && EXPRESSION2'
1 True if both EXPRESSION1 and EXPRESSION2 are true.
1
1 'EXPRESSION1 || EXPRESSION2'
1 True if either EXPRESSION1 or EXPRESSION2 is true.
1
1 The '&&' and '||' operators do not evaluate EXPRESSION2 if the
1 value of EXPRESSION1 is sufficient to determine the return value of
1 the entire conditional expression.
1