Differences between revisions 7 and 11 (spanning 4 versions)
Revision 7 as of 2023-01-20 17:23:17
Size: 4147
Comment:
Revision 11 as of 2023-01-21 22:20:55
Size: 4183
Comment:
Deletions are marked like this. Additions are marked like this.
Line 16: Line 16:
Both are equivalent, POSIX compliant, and portable. Both are equivalent, POSIX compliant, and portable. `test(1)` sets the exit code to 0 if the test is true, and 1 if false.
Line 18: Line 18:
Shell tests are frequently used with [[Shell/Logic#Conditional_Logic|conditional logic. Shell tests are frequently used with [[Shell/Logic#Conditional_Logic|conditional logic]].
Line 22: Line 22:
  :
elif [ TEST ]; then
  :
else
Line 77: Line 73:
|| `-d fn` || directory exists || || `-d fn` || directory exists       ||
Line 97: Line 93:
|| `fn1 -ef fn2` || fn1 has same device and inode numbers as fn2 ||
|| `fn1 -nt fn2` || fn1 is newer (modification date) than fn2 ||
|| `fn1 -ot fn2` || fn1 is older (modification date) than fn2 ||
Line 107: Line 100:
To negate a test, insert `!` before the expression. To negate a test, insert `!` before the expression. Note that negation is applied to the '''last''' test only.
Line 110: Line 103:
if [ ! EXPR ]; then if [ ! TEST ]; then
Line 115: Line 108:
The `test` command supports options for `AND` and `OR` operations (`-a` and `-o` respectively). Do not use these. Instead, consider a less ambiguous grammar construct. The `test(1)` command supports options for `AND` and `OR` operations (`-a` and `-o` respectively). '''Do not use these.''' The `test(1)` command also respects parentheses for ordering operations. '''Again, do not use these.'''
Line 118: Line 111:
if [ EXPR ] && [ EXPR ]; then if [ TEST -a \( TEST -o TEST \) ]; then
  :
fi
}}}

Instead, consider a less ambiguous grammar construct.

{{{
if [ TEST ] && [ TEST ]; then
Line 122: Line 123:
if [ EXPR ] || [ EXPR ]; then if [ TEST ] || [ TEST ]; then

Shell Test


Usage

There are two interfaces to shell tests:

  • test(1)

  • the alias [ (which requires a ] following all operands, strings, and expressions)

Both are equivalent, POSIX compliant, and portable. test(1) sets the exit code to 0 if the test is true, and 1 if false.

Shell tests are frequently used with conditional logic.

if [ TEST ]; then
  :
fi


Variable Tests

Usage

True if...

var1 = var2

var1 is equivalent to var2

var1 != var2

var1 is not equivalent to var2

-z var

string length of var is 0

-n var

string length of var is not 0

var1 -eq var2

var1 is numerically equal to var2

var1 -ne var2

var1 is numerically inequal to var2

var1 -gt var2

var1 is numerically greater than var2

var1 -ge var2

var1 is numerically greater than/ equal to to var2

var1 -lt var2

var1 is numerically lesser than var2

var1 -le var2

var1 is numerically lesser than/ equal to to var2

Caveats and Warnings

It is absolutely critical for variables to be quoted within tests, because they are evaluated by the shell. Even so, if any variables can be set to an empty string (or unset), these tests can suffer from instability. For example, "$var" = foo could evaluate to = foo, which would raise an error since the = operator requires values on either side. The common workaround is prefixing with an arbitrary letter, typically "x".

In summary:

# bad
if [ $var = foo ]; then
  :
fi

# good
if [ x"$var" = "xfoo" ]; then
  :
fi


File Tests

These are probably what you are looking for.

Usage

True if...

-d fn

directory exists

-e fn

file exists

These rarely are useful.

Usage

True if...

-b fn

file exists and is a block special file

-c fn

file exists and is a character special file

-f fn

file exists and is a regular file

-g fn

file exists and its set-group-id bit is set

-h fn

symbolic link exists (same as -L)

-p fn

named pipe (FIFO) exists

-r fn

file exists and is readable

-s fn

file exists and its size is greater than zero

-t fn

file descriptor is open and refers to a terminal

-u fn

file exists and its set-user-id bit is set

-w fn

file exists and is writable

-x fn

file exists and is executable

-L fn

symbolic link exists (same as -h)

-S fn

socket exists


Compound Logic

To negate a test, insert ! before the expression. Note that negation is applied to the last test only.

if [ ! TEST ]; then
  :
fi

The test(1) command supports options for AND and OR operations (-a and -o respectively). Do not use these. The test(1) command also respects parentheses for ordering operations. Again, do not use these.

if [ TEST -a \( TEST -o TEST \) ]; then
  :
fi

Instead, consider a less ambiguous grammar construct.

if [ TEST ] && [ TEST ]; then
  :
fi

if [ TEST ] || [ TEST ]; then
  :
fi


CategoryRicottone

Shell/Test (last edited 2023-01-21 22:20:55 by DominicRicottone)