Created SC2252 (markdown)

Vidar Holen
2019-06-02 09:32:42 -07:00
parent 2b37ef5e7b
commit 492d5b693c

43
SC2252.md Normal file

@@ -0,0 +1,43 @@
## You probably wanted && here, otherwise it's always true.
### Problematic code:
```sh
if [ "$1" != foo ] || [ "$1" != bar ]
then
echo "$1 is not foo or bar"
fi
```
### Correct code:
```sh
if [ "$1" != foo ] && [ "$1" != bar ]
then
echo "$1 is not foo or bar"
fi
```
### Rationale:
This is not a bash issue, but a simple, common logical mistake applicable to all languages.
`[ "$1" != foo ] || [ "$1" != bar ]` is always true (when `foo != bar`):
* If `$1 = foo` then `$1 != bar` is true, so the statement is true.
* If `$1 = bar` then `$1 != foo` is true, so the statement is true.
* If `$1 = cow` then `$1 != foo` is true, so the statement is true.
`[ $1 != foo ] && [ $1 != bar ]` matches when `$1` is neither `foo` nor `bar`:
* If `$1 = foo`, then `$1 != foo` is false, so the statement is false.
* If `$1 = bar`, then `$1 != bar` is false, so the statement is false.
* If `$1 = cow`, then both `$1 != foo` and `$1 != bar` is true, so the statement is true.
This statement is identical to `! [ "$1" = foo ] || [ "$1" = bar ]`, which also works correctly (by [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws))
This warning is equivalent to [[SC2055]] and [[SC2056]], which trigger for intra-`test` expressions and arithmetic contexts respectively.
### Exceptions
Rare.