diff --git a/SC2252.md b/SC2252.md new file mode 100644 index 0000000..de6a8e1 --- /dev/null +++ b/SC2252.md @@ -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. \ No newline at end of file