Conditional Constructs (Bash Reference Manual)
Next: Command Grouping, Previous: Looping Constructs, Up: Compound Commands [Contents][Index]
3.2.5.2 Conditional Constructs
ifThe syntax of the
ifcommand is:if test-commands; then consequent-commands; [elif more-test-commands; then more-consequents;] [else alternate-consequents;] fi
The
test-commandslist is executed, and if its return status is zero, theconsequent-commandslist is executed. Iftest-commandsreturns a non-zero status, eacheliflist is executed in turn, and if its exit status is zero, the correspondingmore-consequentsis executed and the command completes. If ‘else alternate-consequents’ is present, and the final command in the finaliforelifclause has a non-zero exit status, thenalternate-consequentsis executed. The return status is the exit status of the last command executed, or zero if no condition tested true.caseThe syntax of the
casecommand is:case word in [ [(] pattern [| pattern]…) command-list ;;]… esaccasewill selectively execute thecommand-listcorresponding to the firstpatternthat matchesword. The match is performed according to the rules described below in Pattern Matching. If thenocasematchshell option (see the description ofshoptin The Shopt Builtin) is enabled, the match is performed without regard to the case of alphabetic characters. The ‘|’ is used to separate multiple patterns, and the ‘)’ operator terminates a pattern list. A list of patterns and an associated command-list is known as aclause.Each clause must be terminated with ‘
;;’, ‘;&’, or ‘;;&’. Thewordundergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal (see Shell Parameter Expansion) before matching is attempted. Eachpatternundergoes tilde expansion, parameter expansion, command substitution, and arithmetic expansion.There may be an arbitrary number of
caseclauses, each terminated by a ‘;;’, ‘;&’, or ‘;;&’. The first pattern that matches determines the command-list that is executed. It’s a common idiom to use ‘*’ as the final pattern to define the default case, since that pattern will always match.Here is an example using
casein a script that could be used to describe one interesting feature of an animal:echo -n "Enter the name of an animal: " read ANIMAL echo -n "The $ANIMAL has " case $ANIMAL in horse | dog | cat) echo -n "four";; man | kangaroo ) echo -n "two";; *) echo -n "an unknown number of";; esac echo " legs."
If the ‘
;;’ operator is used, no subsequent matches are attempted after the first pattern match. Using ‘;&’ in place of ‘;;’ causes execution to continue with thecommand-listassociated with the next clause, if any. Using ‘;;&’ in place of ‘;;’ causes the shell to test the patterns in the next clause, if any, and execute any associatedcommand-liston a successful match, continuing the case statement execution as if the pattern list had not matched.The return status is zero if no
patternis matched. Otherwise, the return status is the exit status of thecommand-listexecuted.selectThe
selectconstruct allows the easy generation of menus. It has almost the same syntax as theforcommand:select name [in words …]; do commands; done
The list of words following
inis expanded, generating a list of items. The set of expanded words is printed on the standard error output stream, each preceded by a number. If the ‘in words’ is omitted, the positional parameters are printed, as if ‘in "$@"’ had been specified. ThePS3prompt is then displayed and a line is read from the standard input. If the line consists of a number corresponding to one of the displayed words, then the value ofnameis set to that word. If the line is empty, the words and prompt are displayed again. IfEOFis read, theselectcommand completes. Any other value read causesnameto be set to null. The line read is saved in the variableREPLY.The
commandsare executed after each selection until abreakcommand is executed, at which point theselectcommand completes.Here is an example that allows the user to pick a filename from the current directory, and displays the name and index of the file selected.
select fname in *; do echo you picked $fname \($REPLY\) break; done((…))(( expression ))
The arithmetic
expressionis evaluated according to the rules described below (see Shell Arithmetic). If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent tolet "expression"
See Bash Builtins, for a full description of the
letbuiltin.Bash/docs/latest/…[[../ expression ]]
Return a status of 0 or 1 depending on the evaluation of the conditional expression
expression. Expressions are composed of the primaries described below in Bash Conditional Expressions. Word splitting and filename expansion are not performed on the words between the[[../and]]; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed. Conditional operators such as ‘-f’ must be unquoted to be recognized as primaries.When used with
[[../, the ‘<’ and ‘>’ operators sort lexicographically using the current locale.When the ‘
==’ and ‘!=’ operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if theextglobshell option were enabled. The ‘=’ operator is identical to ‘==’. If thenocasematchshell option (see the description ofshoptin The Shopt Builtin) is enabled, the match is performed without regard to the case of alphabetic characters. The return value is 0 if the string matches (‘==’) or does not match (‘!=’) the pattern, and 1 otherwise. Any part of the pattern may be quoted to force the quoted portion to be matched as a string.An additional binary operator, ‘
=~’, is available, with the same precedence as ‘==’ and ‘!=’. When it is used, the string to the right of the operator is considered a POSIX extended regular expression and matched accordingly (using the POSIXregcompandregexecinterfaces usually described in regex(3)). The return value is 0 if the string matches the pattern, and 1 otherwise. If the regular expression is syntactically incorrect, the conditional expression’s return value is 2. If thenocasematchshell option (see the description ofshoptin The Shopt Builtin) is enabled, the match is performed without regard to the case of alphabetic characters. Any part of the pattern may be quoted to force the quoted portion to be matched as a string. Bracket expressions in regular expressions must be treated carefully, since normal quoting characters lose their meanings between brackets. If the pattern is stored in a shell variable, quoting the variable expansion forces the entire pattern to be matched as a string.The pattern will match if it matches any part of the string. Anchor the pattern using the ‘
^’ and ‘$’ regular expression operators to force it to match the entire string. The array variableBASH_REMATCHrecords which parts of the string matched the pattern. The element ofBASH_REMATCHwith index 0 contains the portion of the string matching the entire regular expression. Substrings matched by parenthesized subexpressions within the regular expression are saved in the remainingBASH_REMATCHindices. The element ofBASH_REMATCHwith indexnis the portion of the string matching thenth parenthesized subexpression.For example, the following will match a line (stored in the shell variable
line) if there is a sequence of characters anywhere in the value consisting of any number, including zero, of characters in thespacecharacter class, zero or one instances of ‘a’, then a ‘b’:[[../ $line =~ [[:space:]]*(a)?b ]]
That means values like ‘
aab’ and ‘aaaaaab’ will match, as will a line containing a ‘b’ anywhere in its value.Storing the regular expression in a shell variable is often a useful way to avoid problems with quoting characters that are special to the shell. It is sometimes difficult to specify a regular expression literally without using quotes, or to keep track of the quoting used by regular expressions while paying attention to the shell’s quote removal. Using a shell variable to store the pattern decreases these problems. For example, the following is equivalent to the above:
pattern='[[../:space:]]*(a)?b' [[../ $line =~ $pattern ]]
If you want to match a character that’s special to the regular expression grammar, it has to be quoted to remove its special meaning. This means that in the pattern ‘
xxx.txt’, the ‘.’ matches any character in the string (its usual regular expression meaning), but in the pattern ‘"xxx.txt"’ it can only match a literal ‘.’. Shell programmers should take special care with backslashes, since backslashes are used both by the shell and regular expressions to remove the special meaning from the following character. The following two sets of commands are not equivalent:pattern='\.' [[../ ]] [[../ . =~ \]] [[../ ]] [[../ . =~ '\]]
The first two matches will succeed, but the second two will not, because in the second two the backslash will be part of the pattern to be matched. In the first two examples, the backslash removes the special meaning from ‘
.’, so the literal ‘.’ matches. If the string in the first examples were anything other than ‘.’, say ‘a’, the pattern would not match, because the quoted ‘.’ in the pattern loses its special meaning of matching any single character.Expressions may be combined using the following operators, listed in decreasing order of precedence:
( expression )Returns the value of
expression. This may be used to override the normal precedence of operators.! expressionTrue if
expressionis false.expression1 && expression2True if both
expression1andexpression2are true.expression1 || expression2True if either
expression1orexpression2is true.
The
&&and||operators do not evaluateexpression2if the value ofexpression1is sufficient to determine the return value of the entire conditional expression.
Next: Command Grouping, Previous: Looping Constructs, Up: Compound Commands [Contents][Index]