From 492d5b693cd7e941ae82cf5154c88a4c39a55c97 Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sun, 2 Jun 2019 09:32:42 -0700 Subject: [PATCH] Created SC2252 (markdown) --- SC2252.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 SC2252.md 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