Читать книгу Linux Bible - Christopher Negus - Страница 207
The ″if…then″ statements
ОглавлениеThe most commonly used programming construct is conditional execution, or the if
statement. It is used to perform actions only under certain conditions. There are several variations of if
statements for testing various types of conditions.
The first if…then
example tests if VARIABLE
is set to the number 1
. If it is, then the echo
command is used to say that it is set to 1
. The fi
statement then indicates that the if
statement is complete, and processing can continue.
VARIABLE=1 if [ $VARIABLE -eq 1 ] ; then echo "The variable is 1" fi
Instead of using -eq
, you can use the equal sign (=
), as shown in the following example. The =
works best for comparing string values, while -eq
is often better for comparing numbers. Using the else
statement, different words can be echoed if the criterion of the if
statement isn't met ($STRING = ″Friday″
). Keep in mind that it's good practice to put strings in double quotes.
STRING="Friday" if [ $STRING = "Friday" ] ; then echo "WhooHoo. Friday." else echo "Will Friday ever get here?" fi
You can also reverse tests with an exclamation mark (!
). In the following example, if STRING
is not Monday
, then ″At least it's not Monday″
is echoed.
STRING="FRIDAY" if [ "$STRING" != "Monday" ] ; then echo "At least it's not Monday" fi
In the following example, elif
(which stands for “else if”) is used to test for an additional condition (for example, whether filename
is a file or a directory).
filename="$HOME" if [ -f "$filename" ] ; then echo "$filename is a regular file" elif [ -d "$filename" ] ; then echo "$filename is a directory" else echo "I have no idea what $filename is" fi
As you can see from the preceding examples, the condition you are testing is placed between square brackets [ ]
. When a test expression is evaluated, it returns either a value of 0, meaning that it is true, or a 1, meaning that it is false. Notice that the echo
lines are indented. The indentation is optional and done only to make the script more readable.
Table 7.1 lists the conditions that are testable and is quite a handy reference. (If you're in a hurry, you can type help test on the command line to get the same information.)
TABLE 7.1 Operators for Test Expressions
Operator | What Is Being Tested? |
-a file | Does the file exist? (same as -e) |
-b file | Is the file a block special device? |
-c file | Is the file character special (for example, a character device)? Used to identify serial lines and terminal devices. |
-d file | Is the file a directory? |
-e file | Does the file exist? (same as -a) |
-f file | Does the file exist, and is it a regular file (for example, not a directory, socket, pipe, link, or device file)? |
-g file | Does the file have the set group id (SGID) bit set? |
-h file | Is the file a symbolic link? (same as -L) |
-k file | Does the file have the sticky bit set? |
-L file | Is the file a symbolic link? |
-n string | Is the length of the string greater than 0 bytes? |
-O file | Do you own the file? |
-p file | Is the file a named pipe? |
-r file | Is the file readable by you? |
-s file | Does the file exist, and is it larger than 0 bytes? |
-S file | Does the file exist, and is it a socket? |
-t fd | Is the file descriptor connected to a terminal? |
-u file | Does the file have the set user id (SUID) bit set? |
-w file | Is the file writable by you? |
-x file | Is the file executable by you? |
-z string | Is the length of the string 0 (zero) bytes? |
expr1 -a expr2 | Are both the first expression and the second expression true? |
expr1 -o expr2 | Is either of the two expressions true? |
file1 -nt file2 | Is the first file newer than the second file (using the modification time stamp)? |
file1 -ot file2 | Is the first file older than the second file (using the modification time stamp)? |
file1 -ef file2 | Are the two files associated by a link (a hard link or a symbolic link)? |
var1 = var2 | Is the first variable equal to the second variable? |
var1 -eq var2 | Is the first variable equal to the second variable? |
var1 -ge var2 | Is the first variable greater than or equal to the second variable? |
var1 -gt var2 | Is the first variable greater than the second variable? |
var1 -le var2 | Is the first variable less than or equal to the second variable? |
var1 -lt var2 | Is the first variable less than the second variable? |
var1 != var2 | Is the first variable not equal to the second variable? |
var1 -ne var2 | Is the first variable not equal to the second variable? |
There is also a special shorthand method of performing tests that can be useful for simple one-command actions. In the following example, the two pipes (||
) indicate that if the directory being tested for doesn't exist (-d dirname
), then make the directory (mkdir $dirname
):
# [ test ] || action # Perform simple single command if test is false dirname="/tmp/testdir" [ -d "$dirname" ] || mkdir "$dirname"
Instead of pipes, you can use two ampersands to test if something is true. In the following example, a command is being tested to see if it includes at least three command-line arguments:
# [ test ] && {action} # Perform simple single action if test is true [ $# -ge 3 ] && echo "There are at least 3 command line arguments."
You can combine the &&
and ||
operators to make a quick, one-line if…then…else
. The following example tests that the directory represented by $dirname
already exists. If it does, a message says the directory already exists. If it doesn't, the statement creates the directory:
# dirname=mydirectory [ -e $dirname ] && echo $dirname already exists || mkdir $dirname