if Statements
Syntax
if commands; thencommands[elif commands; thencommands...][elsecommands]fi
- Command with exit status of 0 is evaluated as true, otherwise is is evaluated as false.
If a list of commands follows if, the last command in the list is evaluated.
Examples
trueandfalseare builtin commands that do nothing except terminate with either a 0 and 1 exit status respectively. ```bash function test_if() { if true; then echo ‘true’ else echo ‘false’ fiif false; then echo ‘true’ else echo ‘false’ fi }
test_if # call function test_if
true
false
<a name="DayVW"></a>### Using `test` or `[ ]`Both `test` and `[` are actually commands. In bash they are builtins, but they also exist as programs in /usr/bin for use with other shells. <br />`[` command requiring that the `]` character be provided as its **final argument**```bashif test expression; thencommandsfi# orif [ expression ]; thencommandsfi
File Expressions
| Expression | Is true if: |
|---|---|
file1 -ef file2 |
file1 and file2 have the same inode numbers (the two filenames refer to the same file by hard linking). |
file1 -nt file2 |
file1 is newer than file2. |
file1 -ot file2 |
file1 is older than file2. |
-b file |
file exists and is a block-special (device) file. |
-c file |
file exists and is a character-special (device) file. |
-d file |
file exists and is a directory. |
-e file |
file exists. |
-f file |
file exists and is a regular file. |
-g file |
file exists and is set-group-ID. |
-G file |
file exists and is owned by the effective group ID. |
-k file |
file exists and has its “sticky bit” set. |
-L file |
file exists and is a symbolic link. |
-O file |
file exists and is owned by the effective user ID. |
-p file |
file exists and is a named pipe. |
-r file |
file exists and is readable (has readable permission for the effective user). |
-s file |
file exists and has a length greater than zero. |
-S file |
file exists and is a network socket. |
-t fd |
fd is a file descriptor directed to/from the terminal. This can be used to determine whether standard input/output/error is being redirected. |
-u file |
file exists and is setuid. |
-w file |
file exists and is writable (has write permission for the effective user). |
-x file |
file exists and is executable (has execute/search permission for the effective user). |
String Expressions
| Expression | Is true if: |
|---|---|
string |
string is not null. |
-n string |
The length of string is greater than zero. |
-z string |
The length of string is zero. |
string1 = string2string1 == string2 |
string1 and string2 are equal. Single or double equal signs may be used. The use of double equal signs is greatly preferred, but it is not POSIX compliant. |
string1 != string2 |
string1 and string2 are not equal. |
string1 > string2 |
string1 sorts after string2. |
string1 < string2 |
string1 sorts before string2. |
Integers Expressions
| Expression | Is true if: |
|---|---|
integer1 -eq integer2 |
integer1 is equal to integer2. |
integer1 -ne integer2 |
integer1 is not equal to integer2. |
integer1 -le integer2 |
integer1 is less than or equal to integer2. |
integer1 -lt integer2 |
integer1 is less than integer2. |
integer1 -ge integer2 |
integer1 is greater than or equal to integer2. |
integer1 -gt integer2 |
integer1 is greater than integer2. |
Using [[ ]]
Modern versions of bash include a compound command that acts as an enhanced replacement for test. It uses the following syntax:[[ expression ]]expression
- All expressions that
testand[ ]support string =~ regexfile == filename_pattern```bash if [[ “$INT” =~ ^-?[0-9]+$ ]]; then echo “$INT is an integer” fi
FILE=foo.bar if [[ $FILE == foo. ]]; then echo “$FILE matches pattern ‘foo.‘“ fi
<a name="ygGs1"></a>
### Using `(( ))` for Integers
`(( ))` is used to perform arithmetic truth tests. An arithmetic truth testresults in true if the result of the arithmetic evaluation is non-zero.<br />`**((integer1 operator integer2))**`<br />`**operator **`
- `**==**` `<` `<=` `>` `>=` ...
See also ??
```bash
if (( INT % 2 == 0 )); then
echo "$INT is even"
fi
Combining Expressions
| Logical Operation | test and [] | [[ ]] and (( )) |
|---|---|---|
| AND | -a | && |
| OR | -o | || |
| NOT | ! | ! |
[ "$INT" -ge "$MIN_VAL" -a "$INT" -le "$MAX_VAL" ]
[ ! \( "$INT" -ge "$MIN_VAL" -a "$INT" -le "$MAX_VAL" \) ]
[[ "$INT" -ge "$MIN_VAL" && "$INT" -le "$MAX_VAL" ]]
[[ ! ("$INT" -ge "$MIN_VAL" && "$INT" -le "$MAX_VAL") ]]
Control Operators: Another Way to Branch
command1 && command2command1 || command2
$ mkdir temp && cd temp
$ [[ -d temp ]] || mkdir temp
while Statement
Syntax
while commands...; do
commands...
continue
break
done
$ while commands...; do commands...; done
Examples
Read lines from a file
#!/bin/bash
# while-read: read lines from a file
while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
"$distro" \
"$version" \
"$release"
done < distros.txt
#!/bin/bash
# while-read2: read lines from a file
sort -k 1,1 -k 2n distros.txt | while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
"$distro" \
"$version" \
"$release"
done
until Statement
The until compound command is much like while, except instead of exiting a loop when a non-zero exit status is encountered, it does the opposite.
case Statement
Syntax
case word in
[pattern [| pattern]...) commands ;;[&]]...
esac
Patterns
| Pattern | Description |
|---|---|
| a) | Matches if word equals a. |
| [[:alpha:]]) | Matches if word is a single alphabetic character. |
| ???) | Matches if word is exactly three characters long. |
| *.txt) | Matches if word ends with the characters .txt. |
| *) | Matches any value of word. It is good practice to include this as the last pattern in a case command to catch any values of word that did not match a previous pattern, that is, to catch any possible invalid values. |
Examples
#!/bin/bash
# case-menu: a menu driven system information program
clear
echo "
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
"
read -p "Enter selection [0-3] > "
case "$REPLY" in
0) echo "Program terminated."
exit
;;
1) echo "Hostname: $HOSTNAME"
uptime
;;
2) df -h
;;
3) if [[ "$(id -u)" -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh "$HOME"
fi
;;
*) echo "Invalid entry" >&2
exit 1
;;
esac
#!/bin/bash
read -p "enter word > "
case "$REPLY" in
[[:alpha:]]) echo "is a single alphabetic character." ;;
[ABC][0-9]) echo "is A, B, or C followed by a digit." ;;
???) echo "is three characters long." ;;
*.txt) echo "is a word ending in '.txt'" ;;
*) echo "is something else." ;;
esac
#!/bin/bash
# case4-1: test a character
read -n 1 -p "Type a character > "
echo
case "$REPLY" in
[[:upper:]]) echo "'$REPLY' is upper case." ;;
[[:lower:]]) echo "'$REPLY' is lower case." ;;
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;
[[:digit:]]) echo "'$REPLY' is a digit." ;;
[[:graph:]]) echo "'$REPLY' is a visible character." ;;
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;
[[:space:]]) echo "'$REPLY' is a whitespace character." ;;
[[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;
esac
Performing Multiple Actions
#!/bin/bash
# case4-2: test a character
read -n 1 -p "Type a character > "
echo
case "$REPLY" in
[[:upper:]]) echo "'$REPLY' is upper case." ;;&
[[:lower:]]) echo "'$REPLY' is lower case." ;;&
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;&
[[:digit:]]) echo "'$REPLY' is a digit." ;;&
[[:graph:]]) echo "'$REPLY' is a visible character." ;;&
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;&
[[:space:]]) echo "'$REPLY' is a whitespace character." ;;&
[[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;&
esac
for Statement
Traditional Shell Form
Syntax
for variable [in words]; do
commands
done
$ for variable [in words]; do commands; done
If the optional
in wordsportion of theforcommand is omitted,fordefaults to processing the positional parameters.
Examples
$ for i in A B C D; do echo $i; done
$ for i in {A..D}; do echo $i; done
for i in distros*.txt; do
# By adding a test for file existence, we will ignore a failed expansion.
if [[ -e "$i" ]]; then
echo "$i"
fi
done
#!/bin/bash
# longest-word2: find longest string in a file
for i; do
if [[ -r "$i" ]]; then
max_word=
max_len=0
for j in $(strings "$i"); do
len="$(echo -n "$j" | wc -c)"
if ((len > max_len)); then
max_len="$len"
max_word="$j"
fi
done
echo "$i: '$max_word' ($max_len characters)"
fi
done
C Language Form
Syntax
for (( expression1; expression2; expression3 )); do
commands
done
# In terms of behavior, this form is equivalent to the following construct.
(( expression1 ))
while (( expression2 )); do
commands
(( expression3 ))
done
Examples
#!/bin/bash
# simple_counter: demo of C style for command
for (( i=0; i<5; i=i+1 )); do
echo $i
done
The C language form of
foris useful anytime a numeric sequence is needed.
