{"id":148,"date":"2020-01-27T14:29:15","date_gmt":"2020-01-27T22:29:15","guid":{"rendered":"https:\/\/www.jwdev.com\/?p=148"},"modified":"2020-02-16T14:14:42","modified_gmt":"2020-02-16T22:14:42","slug":"native-bash-semver-check","status":"publish","type":"post","link":"https:\/\/www.jwdev.com\/?p=148","title":{"rendered":"(almost) Native BASH semver CHECK"},"content":{"rendered":"\n<p>Recently I needed a simple way to compare semver strings in a BASH script and was unable to find a solution that I liked so I wrote one. Why almost-native BASH? Leveraging the common available <code>sort<\/code> utility avoids re-implementing the version sort logic, reduces potential bugs and  size of the function to a simple 3 lines vs 30+ lines for most BASH-native solutions. <\/p>\n\n\n\n<p>This is working well in environments I manage. If you notice any bugs or issues please comment. <\/p>\n\n\n\n<p>Function returns a standard -1, 0, 1 response. Basic unit tests included to validate functionality and provide example usage.<\/p>\n\n\n\n<p>Enjoy!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env bash\n\nfunction semver_check {\n  # sort low->high then pick the last one (highest)\n  local HV; HV=$(echo -e \"$1\\n$2\" |sort -V |tail -1)\n  # They're not the same and $1 is not the high version = -1\n  [[ \"$1\" != \"$2\" &amp;&amp; \"$1\" != \"$HV\" ]] &amp;&amp; echo -1 &amp;&amp; return\n  # 0 = they're the same; 1 = not the same\n  [[ \"$1\" == \"$2\" ]]; echo $?\n}\n\n#\n# TESTS\n#\n\nLV=\"1.2.3\"\nHV=\"2.3.4\"\n\nARGS=(\"Test A: Ver1 == Ver2\" \"$LV\" \"$LV\")\necho -n \"${ARGS[*]} \"\n[[ $(semver_check \"${ARGS[1]}\" \"${ARGS[2]}\") -eq 0 ]] &amp;&amp; echo \"PASS\" || echo \"FAIL\"\n\nARGS=(\"Test B: Ver1 &lt; Ver2\" \"$LV\" \"$HV\")\necho -n \"${ARGS[*]} \"\n[[ $(semver_check \"${ARGS[1]}\" \"${ARGS[2]}\") -lt 0 ]] &amp;&amp; echo \"PASS\" || echo \"FAIL\"\n\nARGS=(\"Test C: Ver1 > Ver2\" \"$HV\" \"$LV\")\necho -n \"${ARGS[*]} \"\n[[ $(semver_check \"${ARGS[1]}\" \"${ARGS[2]}\") -gt 0 ]] &amp;&amp; echo \"PASS\" || echo \"FAIL\"\n\nARGS=(\"Test D: Ver1 >= Ver2\" \"$HV\" \"$LV\")\necho -n \"${ARGS[*]} \"\nRESULT=\"PASS\"\n[[ $(semver_check \"${ARGS[1]}\" \"${ARGS[2]}\") -ge 0 ]] || RESULT=\"FAIL\"\n[[ $(semver_check \"${ARGS[1]}\" \"${ARGS[1]}\") -ge 0 ]] || RESULT=\"FAIL\"\necho ${RESULT}\n\nARGS=(\"Test E: Ver1 &lt;= Ver2\" \"$LV\" \"$HV\")\necho -n \"${ARGS[*]} \"\nRESULT=\"PASS\"\n[[ $(semver_check \"${ARGS[1]}\" \"${ARGS[2]}\") -le 0 ]] || RESULT=\"FAIL\"\n[[ $(semver_check \"${ARGS[1]}\" \"${ARGS[1]}\") -le 0 ]] || RESULT=\"FAIL\"\necho ${RESULT}\n<\/code><\/pre>\n\n\n\n<p><strong>Addendum:<\/strong> The <code>sort<\/code> binary dependency must support natural version sort option (<code>-V, --version-sort<\/code>) This option is available on GNU coreutils 7+ and is also available on Mac OS 10.14+<br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently I needed a simple way to compare semver strings in a BASH script and was unable to find a solution that I liked so I wrote one. Why almost-native BASH? Leveraging the common available sort utility avoids re-implementing the version sort logic, reduces potential bugs and size of the function to a simple 3 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,21,10],"tags":[],"_links":{"self":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts\/148"}],"collection":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=148"}],"version-history":[{"count":13,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts\/148\/revisions"}],"predecessor-version":[{"id":163,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts\/148\/revisions\/163"}],"wp:attachment":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}