> For the complete documentation index, see [llms.txt](https://freebsdfrau.gitbook.io/serious-shell-programming/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://freebsdfrau.gitbook.io/serious-shell-programming/basics/conditionals/parameter-test.md).

# 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.
