The [[...]] Command

The [[...]] command is used to evaluate conditional expressions with file attributes, strings, integers, and more. The basic format is:

[[expression]] 

where expression is the condition you are evaluating. There must be whitespace after the opening brackets, and before the closing brackets. Whitespace must also separate the expression arguments and operators. For example, these are incorrect:

					[[$X=$Y]]
					[[$X = $Y]]
				

while this is correct:

					[[ $X == $Y ]]
				

Notice that there is white space between $X, $Y, and the = operator.

If the expression evaluates to true, then a zero exit status is returned, otherwise the expression evaluates to false and a non-zero exit status is returned.

If you are familiar with the test and [...] commands, then you'll recognize that [[...]] is just a new and improved version of the same commands. It basically functions the same way, except that a number of new operators are available.

Table 8.2. [[...]] String Operators
–n string true if length of string is not zero
–o option true if option is set
–z string true if length of string is zero
string1 = string2 true if string1 is equal to string2
string1 != string2 true if string1 is not equal to string2
string = pattern true if string matches pattern
string != pattern true if string does not match pattern
string1 < string2 true if string1 less than string2
string1 > string2 true if string1 greater than string2

Checking Strings

We could use the [[...]] command to check if a variable is set to a certain value. Here, variable X is assigned abc, then evaluated in this expression:

						$ X=abc
						$ [[ $X = abc ]] && print "X is set to abc"
						X is set to abc
					

Using the test and [...] commands, the same command could be written as:

						test "$X" = abc && print "X is set to abc"
					

or

						[ "$X" = abc ] && print "X is set to abc"
					

To check if a variable is set to null, the –z option can be used:

						[[ —z $VAR ]] && print "VAR is set to null"
					

or it could be compared to the null string like this:

						[[ $VAR = "" ]] && "VAR is set to null"
					

Checking Patterns

The Korn shell also lets you compare strings to patterns. We could check if X begins with a 'a' like this:

							$ X=abc
							$ [[ $X = a* ]] && print "$X matches a*"
							abc matches a*
						

or if it's a three-character string:

							$ [[ $X = ??? ]] && print "$X has exactly 3 
							characters"
							abc has exactly 3 characters
						

Using the +([0–9]) pattern, we could check if X is set to a number:

							$ X=123
							$ [[ $X = +([0—9]) ]] && print "$X is a number"
							123 is a number
						

Table 8.2 lists the most commonly used [[...]] string operators.

Table 8.3. Some [[...]] File Operators
–a file true if file exists.
–d file true if file exists and is a directory.
–f file true if file exists and is a regular file.
–G file true if file exists and its group id matches the effective group id of the current process.
–L file true if file exists and is a symbolic link.
–Ofile true if file exists and its user id matches the effective user id of the current process.
–r file true if file exists and is readable.
–s file true if file exists and its size is greater than zero.
–S file true if file exists and is a socket.
–u file true if file exists and its set user-id bit is set.
–w file true if file exists and is writable.
–x file true if file exists and is executable. If file is a directory, then true indicates that the directory is searchable.
file1 –ef file2 true if file1 exists and is another name for file2.
file1 –nt file2 true if file1 exists and is newer than file2.
file1 – ot file2 true if file1 exists and is older than file2.

Checking File Attributes

Because manipulating files is so important in programming, the Korn shell provides a whole range of file operators. The most basic operation to perform on a file is to see if it exists, and that can be done using the –a operator. This is a new Korn shell file operator. Make sure you don't get it confused with the logical AND operator used by the test and [...] commands, which is also written as –a.

						$ touch tmp
						$ [[ —a tmp ]] && print "File tmp exists"
						File tmp exists
					

This only indicates that it exists, but not much else. It may be a directory, or a symbolic link, but using this operator, that's all we know. If we wanted more information, the –f or –d operators could tell us if a file existed and was a normal file (–f) or if it was just a directory (–d). Let's try the –f operator on the tmp file:

						$ [[ –f tmp ]] && print "File tmp exists and 
						is a regular file"
						File tmp exists and is a regular file
					

If we tried the –d operator on the tmp file, it would evaluate to false, because it isn't a directory:

						$ [[ –d tmp ]] && print "File tmp exists and 
						is a regular file"
						$
					

While on a directory it would evaluate to true:

						$ mkdir tmpdir
						$ [[ –d tmpdir ]] && print "Directory tmp exists"
						Directory tmp exists
					

This conditional command checks if $FILE is readable, and if not, prints an error message and exits:

						[[ –r $FILE ]]||{ print $FILE not readable; exit 1; }
					

while this one checks if $FILE is writable:

						[[ –w $FILE ]]||{ print $FILE not writable; exit 1; }
					

Here are a couple of new file operators: –nt and –ot. They compare two files and return true if file1 is newer than (–nt) or older than (–ot) file2.

						$ touch tfile2
						$ touch tfile1
						$ [[ tfile1 —nt tfile2 ]]&&print "tfile1 is 
						newer than tfile2"
						tfile1 is newer than tfile2
					

Let's switch the files in the expression and try the –ot operator:

						$ [[ tfile2 —ot tfile1 ]]&&print "tfile2 is 
						older than tfile1"
						tfile2 is older than tfile1
					

Table 8.3 lists the most commonly used [[...]] file operators.

Checking Integer Attributes

The [[...]] command provides a few integer operators that allow integers to be compared. It is frequently used to check the number of command-line arguments. This expression evaluates to true if there are less than or equal to three positional parameters set:

						[[ $# —le 3 ]] && print "3 or less args given"
					

The last expression is equivalent to checking if there are less than four positional parameters set:

						[[ $# —lt 4 ]] && print "Less than 4 args given"
					

The number of users logged on could be checked like this:

						$ [[ $(who | wc —l) —gt 10 ]] && print "More 
						than 10 users are logged on"
						More than 10 users are logged on
					

In many cases, the [[...]] integer operators may be sufficient for evaluating expressions that contain integers. To perform other arithmetic operations, use the ((...)) command (discussed in Chapter 6). It offers the same arithmetic comparison operators as the [[...]] command, plus many others. Besides offering more arithmetic operators, the ((...)) command provides substantial performance improvements over the [[...]] and test commands. The last command could also be given as:

						(($(who | wc —l) > 10)) && print "More than 
						10 users are logged on"
					

Using an arithmetic expression, the number of command-line arguments can be checked like this:

						(($# < 4)) && print "Less than 4 args"
					

Table 8.4 lists the most commonly used [[...]] integer operators.

The ! Operator

The ! operator negates the result of any [[...]] expression when used like this:

						[[ !
						expression]]
					

For example, to check if X is not equal to abc:

						$ X=xyz
						$ [[ ! $X = abc ]] && print "$X not equals abc"
						xyz not equals abc
					

or if a file doesn't exist:

						$ rm tmp
						$ [[ ! —f tmp ]] && print "tmp does NOT exist"
						tmp does NOT exist
					

Table 8.4. [[...]] Integer Operators
exp1 –eq exp2 true if exp1 is equal to exp2
exp1 –ne exp2 true if exp1 is not equal to exp2
exp1 –le exp2 true if exp1 is less than or equal to exp2
exp1 –lt exp2 true if exp1 is less than exp2
exp1 –ge exp2 true if exp1 is greater than or equal to exp2
exp1 –gt exp2 true if exp1 is greater than exp2

There is one logical operator that can only be implemented with the ! operator. There is no [[...]] file operator that will evaluate to true on a zero-length file.

						$ >emptyfile
						$ [[ ! —s emptyfile ]] && print "emptyfile is empty"
						emptyfile is empty
					

Compound Expressions

Expressions can also be combined with the && and || operators to form compound expressions.

&& - The AND Operator

The && operator is used with the [[...]] command to test if multiple expressions are true using this format:

[[expression1 && expression2]] 

We could check if two variables were set to specific values like this:

							$ X=abc Y=def
							$ [[ $X = abc && $Y = def ]] && print "X=abc  
							and Y=def"
							X=abc and Y=def
						

This expression checks if the noglob and noclobber options are set:

							[[ —o noglob && —o noclobber ]]
						

Multiple && operators can also be given in one [[...]] command. We could check if three options were set like this:

							[[ —o noglob && —o noclobber && —o bgnice ]]
						

In some versions of the Korn shell, multiple && operators cannot be given in one [[...]] command unless grouped with parentheses.

Table 8.5. Other [[...]] Operators
[[expression1 && expression2]] true if both expression1 and expression2 are true
[[expression1 || expression2]] true either expression1 or expression2 are true
[[(expression)]] true if expression evaluates to true. The ()'s are used to override the precedence rules.
[[ !expression]] true if expression evaluates to false

|| - The OR Operator

The || operator is used with the [[...]] command to test if expression1 OR expression2 are true using this format:

							[[expression1 || expression2]]
						

This expression checks if $FILE was readable or executable:

							[[ —r $FILE || —w $FILE ]]
						

while this one checks if either variable was set to your name:

							[[ $USER=$(whoami) || $LOGNAME=$(whoami) ]]
						

Multiple || operators can also be given in one [[...]] command. We could check if $FILE was readable, writable, or executable like this:

							[[ —r $FILE || —w $FILE || —x $FILE ]]
						

As with the && operator, in some versions of the Korn shell, multiple || operators cannot be given in one [[...]] command unless grouped with parentheses.

[[...]] vs test and [...]

The [[...]] command is preferred to test and [...], since many of the errors associated with test and [...] do not occur. For example, when comparing two variables where one is set to null or unset, the test and [...] commands return a syntax error if the variable is not surrounded in double quotes. Here, X is unset, while Y is set to 1:

						$ unset X
						$ Y=1
					

Without double quotes around the variable names, the test and [...] commands return a syntax error:

						$ test $X = $Y && print "X and Y are equal"
						/bin/ksh: test: argument expected
					

or

						$ [ $X = $Y ] && print "X and Y are equal"
						/bin/ksh: test: argument expected
					

while the [[...]] command does not (unless the nounset option is enabled):

						$ [[ $X = $Y ]] && print "X and Y are equal"
						X and Y are equal
					

Checking File Descriptors

On systems that support the /dev/fd directory for naming open files, the files argument in expressions can be given as /dev/fd/n so that the test is applied to the open file associated with file descriptor n. This command checks to see if standard input (file descriptor 0) is readable:

						$ [[ —r /dev/fd/0 ]] && print "Stdin is readable"
						Stdin is readable
					

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.199.27