
{"id":4903,"date":"2023-09-22T01:55:22","date_gmt":"2023-09-22T05:55:22","guid":{"rendered":"https:\/\/ikriv.com\/blog\/?p=4903"},"modified":"2023-09-22T01:55:52","modified_gmt":"2023-09-22T05:55:52","slug":"stopping-bash-script-on-error-and-what-can-possibly-go-wrong","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=4903","title":{"rendered":"Stopping bash script on error, and what can possibly go wrong"},"content":{"rendered":"<p><b>TL;DR<\/b> Don&#8217;t mix <code>set -e<\/code> and <code>&amp;&amp;<\/code> operators in bash, it&#8217;s not going to work well.<\/p>\n<h2>What is &#8216;set -e&#8217;<\/h2>\n<p>Bash command <code>set -e<\/code> stops the script when any of the script commands fails. Or something like that, the big hairy devil is in the details. Suppose we want to download, build, test, and deploy some code using a bash script. We want to stop the entire script immediately if any of the steps fails. This is not something bash would do by default. We can combine all the steps using the <code>&amp;&amp;<\/code> operator, but in real life it becomes really annoying really quickly, especially for large scripts with long winded commands:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n#!\/bin\/bash\r\ndownload &amp;&amp;\r\ndo_build &amp;&amp;\r\ndo_test &amp;&amp;\r\ndeploy\r\n<\/pre>\n<p>Alternatively, we can put <code>set -e<\/code> in the beginning of the script, and leave the rest as is:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n#!\/bin\/bash\r\nset -e\r\ndownload\r\ndo_build\r\ndo_test\r\ndeploy\r\n<\/pre>\n<h2>&#8216;set -e&#8217; does not mix well with &amp;&amp;<\/h2>\n<p><code>set -e<\/code> comes with quite a few strings attached: in particular, it will stop only for &#8220;simple&#8221; commands. See <a href=\"https:\/\/stackoverflow.com\/questions\/25794905\/why-does-set-e-true-false-true-not-exit\">this Stack Overflow question<\/a> for more details.<\/p>\n<p>Suppose &#8216;do_build&#8217; fails in the following script:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n#!\/bin\/bash\r\nset -e\r\ndownload \r\ndo_build &amp;&amp; do_test\r\ndeploy\r\n<\/pre>\n<p>Will the script stop? No! It will skip the &#8216;do_test&#8217; command and go strait ahead to &#8216;deploy&#8217;. <span style=\"color: #ff0000;\">If &#8216;deploy&#8217; manages to succeed, the whole script succeeds, even though we just failed the build and skipped the test<\/span>. How do I know? The hard way. Our CI build failed in a similar manner, but overall result was &#8220;green&#8221;.<\/p>\n<p>This is not a bug, this is a feature. <code>do_build &amp;&amp; do_test<\/code> is not a simple command, so <code>set -e<\/code> treats it differently.<\/p>\n<p><code>false &amp;&amp; false<\/code> and <code>false &amp;&amp; true<\/code> will NOT stop the script.<\/p>\n<p>On the other hand, <code>false<\/code> on its own, as well as <code>false || false<\/code> and <code>true &amp;&amp; false<\/code> WILL stop the script.<\/p>\n<p>Of course, if you read the documentation carefully, it all has an explanation, but the bottom line is very simple: do not mix <span style=\"text-decoration: line-through;\">driving and alcohol<\/span> <code>set -e<\/code> and operator <code>&amp;&amp;<\/code>. Choose either one or the other, but not both.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR Don&#8217;t mix set -e and &amp;&amp; operators in bash, it&#8217;s not going to work well. What is &#8216;set -e&#8217; Bash command set -e stops the script when any of <a href=\"https:\/\/ikriv.com\/blog\/?p=4903\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[4],"tags":[],"class_list":["entry","author-ikriv","post-4903","post","type-post","status-publish","format-standard","category-hack"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4903","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4903"}],"version-history":[{"count":2,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4903\/revisions"}],"predecessor-version":[{"id":4905,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4903\/revisions\/4905"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}