Parameter test

Combining the test built-in with Parameter Conditionals allows you to not only test values but the conditional expansion of those values. The most common use is perhaps supplying a default value during a test for when a variable is unset or NULL, but parameter testing can also be used for pattern matching without resorting to a case statement.

Test if a variable is set:

[ "${foo+set}" ] # foo is set and non-NULL

By itself, the test built-in ([) will return success (zero exit status) if given a non-NULL string, failure otherwise (non-zero exit status). By itself, the + parameter expansion conditional will expand the alternate value of set when variable foo has been given a value (even if NULL). Combined, the test of [ "${foo+set}" ] returns success if foo is set, even if NULL.

Test if a variable is set to a non-NULL value excluding some value:

[ "${foo#abc}" ] # foo is set, non-NULL, and not abc

Alone, the # parameter expansion feature will trim abc from the value of foo if present. Therefore, if the value of foo is abc, the syntax ${foo#abc} will expand to the NULL string. Combined with the test syntax for testing strings, the syntax [ "${foo#abc}" ] will return success if foo is set, non-NULL, and not abc, failure otherwise.

You can also use the % parameter expansion feature to achieve the same effect.

[ "${foo%abc}" ] # foo is set, non-NULL, and not abc

If foo is unset, NULL, or is equal to abc, the test returns failure, success otherwise. These two tests are therefore the same:

[ "${foo#abc}" ] # foo is non-NULL and not abc
[ "${foo%abc}" ] # foo is non-NULL and not abc

The first parameter test (#) will attempt to remove abc from the beginning of the value while the second (%) will attempt to remove abc from the end of the value. The exit status of the test is only affected if after potentially removing abc (from either end) does the value becomes NULL.

Test if a variable is set to some value matching a pattern:

[ "$foo" != "${foo#bar*}" ] # foo starts with bar
[ "$foo" != "${foo%*bar}" ] # foo ends with bar
[ "$foo" != "${foo#*bar*}" ] # foo contains bar
[ "$foo" != "${foo%*bar*}" ] # foo contains bar

Comparing the conditionally modified expansion of a variable against its original value, the exit status is success if the value was modified, failure otherwise.

Last updated