{"id":428484,"date":"2022-04-06T16:00:55","date_gmt":"2022-04-06T13:00:55","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/"},"modified":"2022-04-06T16:00:55","modified_gmt":"2022-04-06T13:00:55","slug":"how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/","title":{"rendered":"#How To Validate the Syntax of a Linux Bash Script Before Running It"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a2f90f8a496f\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a2f90f8a496f\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#%E2%80%9CHow_To_Validate_the_Syntax_of_a_Linux_Bash_Script_Before_Running_It%E2%80%9D\" >&#8220;How To Validate the Syntax of a Linux Bash Script Before Running It&#8221;<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#Those_Pesky_Bugs\" >Those Pesky Bugs<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#Testing_Is_Difficult\" >Testing Is Difficult<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#Using_Bash_To_Check_Script_Syntax\" >Using Bash To Check Script Syntax<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#The_ShellCheck_Utility\" >The ShellCheck Utility<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#Installing_ShellCheck\" >Installing ShellCheck<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#Using_ShellCheck\" >Using ShellCheck<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/#ShellCheck_Is_Your_Friend\" >ShellCheck Is Your Friend<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"%E2%80%9CHow_To_Validate_the_Syntax_of_a_Linux_Bash_Script_Before_Running_It%E2%80%9D\"><\/span>&#8220;How To Validate the Syntax of a Linux Bash Script Before Running It&#8221;<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<div>\n<figure style=\"width: 1200px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage size-full wp-image-771470\" data-pagespeed-lazy-srcset=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/hero-1.png?width=398&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 400w, https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/hero-1.png?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 1200w\" sizes=\"auto, 400w, 1200w\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/hero-1.png?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"A Linux terminal on laptop screen over a red backdrop.\" width=\"1200\" height=\"675\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><figcaption class=\"wp-caption-text\"><span class=\"type:primaryImage imagecredit\"><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/www.shutterstock.com\/image-vector\/linux-interface-screen-notebook-world-map-321627716\">fatmawati achmad zaenuri\/Shutterstock<\/a><\/span><\/figcaption><\/figure>\n<p>Bugs and typos in Linux Bash <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">script<\/a>s can do dire things when the script is run. Here are some ways to check the syntax of your scripts before you even run them.<\/p>\n<h2 id=\"those-pesky-bugs\"><span class=\"ez-toc-section\" id=\"Those_Pesky_Bugs\"><\/span>Those Pesky Bugs<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Writing code is hard. Or to be more accurate, writing bug-free non-trivial code is hard. And the more lines of code there are in a program or script, the more likely it becomes that there will be bugs in it.<\/p>\n<p>The language you program in has a direct bearing on this. Programming in assembly is much tougher than programming in C, and programming in C is more challenging than programming in Python. The more low-level the language you\u2019re programming in, the more work you have to do yourself. Python might enjoy in-built garbage-collection routines, but C and assembly certainly don\u2019t.<\/p>\n<p>Writing Linux shell scripts poses its own challenges. With a compiled language like C, a program called a compiler reads your source code\u2014the human-readable instructions you type into a text file\u2014and transforms it into a binary executable file. The binary file contains the machine code instructions that the computer can understand and act upon.<\/p>\n<p>The compiler will only generate a binary file if the source code it\u2019s reading and parsing obeys the syntax and other rules of the language. If you spell a\u00a0<em>reserved word<\/em>\u2014one of the command words of the language\u2014or a variable name incorrectly, the compiler will throw an error.<\/p>\n<p>For example, some languages insist you declare a variable before you use it, others are not so fussy. If the language you\u2019re working in requires you to declare variables but you forget to do that, the compiler will throw a different error message. As annoying as these compilation-time errors are, they do catch a lot of problems and force you to address them. But even when you\u2019ve got a program that has no\u00a0<em>syntactical bugs<\/em>\u00a0it doesn\u2019t mean there are no bugs in it. Far from it.<\/p>\n<p>Bugs that are due to\u00a0<em>logical flaws<\/em>\u00a0are usually much harder to spot. If you tell your program to add two and three but you really wanted it to add two and two, you won\u2019t get the answer you expected. But the program is doing what it has been written to do.\u00a0There\u2019s nothing wrong with the composition or syntax of the program. The problem is you. You\u2019ve written a well-formed program that doesn\u2019t do what you wanted.<\/p>\n<h2 id=\"testing-is-difficult\"><span class=\"ez-toc-section\" id=\"Testing_Is_Difficult\"><\/span>Testing Is Difficult<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Thoroughly testing a program, even a simple one, is time-consuming. Running it a few times isn\u2019t enough; you really need to test all execution paths in your code, so that all parts of the code are verified. If the program asks for input, you need to provide a sufficient range of input values to test all conditions\u2014including unacceptable input.<\/p>\n<p>For higher-level languages, unit tests and automated testing help to make thorough testing a manageable exercise. So the question is, are there any tools that we can use to help us write bug-free Bash shell scripts?<\/p>\n<p>The answer is yes, including the Bash shell itself.<\/p>\n<h2 id=\"using-bash-to-check-script-syntax\"><span class=\"ez-toc-section\" id=\"Using_Bash_To_Check_Script_Syntax\"><\/span>Using Bash To Check Script Syntax<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The Bash <code>-n<\/code> (noexec) option tells Bash to read a script and check it for syntactical errors, without running the script. Depending on what your script is intended to do, this can be a lot safer than running it and looking for problems.<\/p>\n<p>Here\u2019s the script we\u2019re going to check. It isn\u2019t complicated, it\u2019s mainly a set of <code>if<\/code> statements. It prompts for, and accepts, a number representing a month. The script decides which season the month belongs to. Obviously, this won\u2019t work if the user provides no input at all, or if they provide invalid input like a letter instead of a digit.<\/p>\n<pre>#! \/bin\/bash&#13;\n&#13;\nread -p \"Enter a month (1 to 12): \" month&#13;\n&#13;\n# did they enter anything?&#13;\nif [ -z \"$month\" ]&#13;\nthen&#13;\n  echo \"You must enter a number representing a month.\"&#13;\n  exit 1&#13;\nfi&#13;\n&#13;\n# is it a valid month?&#13;\nif (( \"$month\" &lt; 1 || \"$month\" &gt; 12)); then&#13;\n  echo \"The month must be a number between 1 and 12.\"&#13;\n  exit 0&#13;\nfi&#13;\n&#13;\n# is it a Spring month?&#13;\nif (( \"$month\" &gt;= 3 &amp;&amp; \"$month\" &lt; 6)); then&#13;\n  echo \"That's a Spring month.\"&#13;\n  exit 0&#13;\nfi&#13;\n&#13;\n# is it a Summer month?&#13;\nif (( \"$month\" &gt;= 6 &amp;&amp; \"$month\" &lt; 9)); then&#13;\n  echo \"That's a Summer month.\"&#13;\n  exit 0&#13;\nfi&#13;\n&#13;\n# is it an Autumn month?&#13;\nif (( \"$month\" &gt;= 9 &amp;&amp; \"$month\" &lt; 12)); then&#13;\n  echo \"That's an Autumn month.\"&#13;\n  exit 0&#13;\nfi&#13;\n&#13;\n# it must be a Winter month&#13;\necho \"That's a Winter month.\"&#13;\nexit 0<\/pre>\n<p>This section checks whether the user has entered anything at all. It tests whether the <code>$month<\/code> variable is unset.<\/p>\n<pre>if [ -z \"$month\" ]&#13;\nthen&#13;\n\u00a0 echo \"You must enter a number representing a month.\"&#13;\n\u00a0 exit 1&#13;\nfi<\/pre>\n<p>This section checks whether they have entered a number between 1 and 12. It also traps invalid input that isn\u2019t a digit, because letters and punctuation symbols don\u2019t translate into numerical values.<\/p>\n<pre># is it a valid month?&#13;\nif (( \"$month\" &lt; 1 || \"$month\" &gt; 12)); then&#13;\n\u00a0 echo \"The month must be a number between 1 and 12.\"&#13;\n\u00a0 exit 0&#13;\nfi<\/pre>\n<p>All of the other If clauses check whether the value in the <code>$month<\/code> variable is between two values. If it is, the month belongs to that season. For example, if the month entered by the user is 6, 7, or 8, it is a Summer month.<\/p>\n<pre># is it a Summer month?&#13;\nif (( \"$month\" &gt;= 6 &amp;&amp; \"$month\" &lt; 9)); then&#13;\n  echo \"That's a Summer month.\"&#13;\n  exit 0&#13;\nfi<\/pre>\n<p>If you want to work through our examples, copy and paste the text of the script into an editor and save it as \u201cseasons.sh.\u201d Then make the script executable by using the <code>chmod<\/code> command:<\/p>\n<pre>chmod +x seasons.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788961\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/1-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Setting the executable permission on a script\" width=\"644\" height=\"55\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><br \/>\nWe can test the script by<\/p>\n<ul>\n<li>Providing no input at all.<\/li>\n<li>Providing a non-numeric input.<\/li>\n<li>Providing a numerical value that is outside the range of 1 to 12.<\/li>\n<li>Providing numerical values within the range of 1 to 12.<\/li>\n<\/ul>\n<p>In all cases, we start the script with the same command. The only difference is the input the user provides when promoted by the script.<\/p>\n<pre>.\/seasons.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788962\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/2-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Testing a script with a variety of valid and invalid inputs\" width=\"644\" height=\"335\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>That seems to work as expected. Let\u2019s have Bash check the syntax of our script. We do this by invoking the <code>-n<\/code> (noexec) option and passing in the name of our script.<\/p>\n<pre>bash -n .\/seasons.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788963\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/3-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Using Bash to test the syntax of a script\" width=\"644\" height=\"75\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>This is a case of \u201cno <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/news\/\" data-internallinksmanager029f6b8e52c=\"2\" title=\"News\" target=\"_blank\" rel=\"noopener\">news<\/a> is good news.\u201d Silently returning us to the command prompt is Bash\u2019s way of saying everything seems OK. Let\u2019s sabotage our script and introduce an error.<\/p>\n<p>We\u2019ll remove the <code>then<\/code> from the first <code>if<\/code> clause.<\/p>\n<pre># is it a valid month?&#13;\nif (( \"$month\" &lt; 1 || \"$month\" &gt; 12)); # \"then\" has been removed&#13;\n  echo \"The month must be a number between 1 and 12.\"&#13;\n  exit 0&#13;\nfi<\/pre>\n<p>Now let\u2019s run the script, first without and then with input from the user.<\/p>\n<pre>.\/seasons.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788964\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/4-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Testing a script with invalid and valid inputs\" width=\"644\" height=\"210\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The first time the script is run the user doesn\u2019t enter a value and so the script terminates. The section that we\u2019ve sabotaged is never reached. The script ends without an error message from Bash.<\/p>\n<p>The second time the script is run, the user provides an input value, and the first if clause is executed to sanity-check the user\u2019s input. That triggers the error message from Bash.<\/p>\n<p>Note that Bash checks the syntax of that clause\u2014and every other line of code\u2014because it doesn\u2019t care about the <em>logic<\/em> of the script.\u00a0The user isn\u2019t prompted to enter a number when Bash checks the script, because the script isn\u2019t running.<\/p>\n<p>The different possible execution paths of the script don\u2019t affect how Bash checks the syntax.\u00a0Bash simply and methodically works its way from the top of the script to the bottom, checking the syntax for every line.<\/p>\n<h2 id=\"the-shellcheck-utility\"><span class=\"ez-toc-section\" id=\"The_ShellCheck_Utility\"><\/span>The ShellCheck Utility<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A linter\u2014named for a C source code checking tool from the heyday of Unix\u2014is a code analysis tool used to detect programming errors, stylistic errors, and suspicious or questionable use of the language. Linters are available for many programming languages and are renowned for being pedantic. Not everything a linter finds is a bug\u00a0<em>per se<\/em>, but anything they do bring to your notice probably deserves attention.<\/p>\n<p><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/www.shellcheck.net\/\">ShellCheck<\/a> is a code analysis tool for shell scripts. It behaves like a linter for Bash.<\/p>\n<p>Let\u2019s put our missing <code>then<\/code> reserved word back into our script, and try something else. We\u2019ll remove the opening bracket \u201c[\u201d from the very first <code>if<\/code> clause.<\/p>\n<pre># did they enter anything?&#13;\nif -z \"$month\" ] # opening bracket \"[\" removed&#13;\nthen&#13;\n  echo \"You must enter a number representing a month.\"&#13;\n  exit 1&#13;\nfi<\/pre>\n<p>if we use Bash to check the script it doesn\u2019t find a problem.<\/p>\n<pre>bash -n seasons.sh<\/pre>\n<pre>.\/seasons.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788965\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/5-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"An error message from a script that passed the syntax checking with no detected issues\" width=\"644\" height=\"170\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>But when we try to <em>run<\/em> the script we see an error message. And, despite the error message, the script continues to execute. This is why some bugs are so dangerous. If the actions taken further on in the script rely on valid input from the user, the script\u2019s behavior will be unpredictable. It could potentially put data at risk.<\/p>\n<p>The reason the Bash <code>-n<\/code> (noexec) option doesn\u2019t find the error in the script is the opening bracket \u201c[\u201d is an external program called <code>[<\/code>. It isn\u2019t part of Bash. It is a shorthand way of using the <code>test<\/code> command.<\/p>\n<p>Bash doesn\u2019t check the use of external programs when it is validating a script.<\/p>\n<h2 id=\"installing-shellcheck\"><span class=\"ez-toc-section\" id=\"Installing_ShellCheck\"><\/span>Installing ShellCheck<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>ShellCheck requires installation. To install it on Ubuntu, type:<\/p>\n<pre>sudo apt install shellcheck<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788966\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/6-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Installing shellcheck on Ubuntu\" width=\"644\" height=\"55\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>To install ShellCheck on Fedora, use this command. Note that the package name is in mixed case, but when you issue the command in the terminal window it is all in lowercase.<\/p>\n<pre>sudo dnf install ShellCheck<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788967\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/fedora.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Installing shellcheck on Fedora\" width=\"644\" height=\"55\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>On Manjaro and similar Arch-based distros, we use <code>pacman<\/code>:<\/p>\n<pre>sudo pacman -S shellcheck<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788968\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/manjaro.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Installing shellcheck on Manjaro\" width=\"644\" height=\"55\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Using_ShellCheck\"><\/span>Using ShellCheck<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let\u2019s try running ShellCheck on our script.<\/p>\n<pre>shellcheck seasons.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788970\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/7-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Checking a script with ShellCheck\" width=\"644\" height=\"55\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>ShellCheck finds the issue and reports it to us, and provides a set of links for further information. If you right-click a link and choose \u201cOpen Link\u201d from the context menu that appears, the link will open in your browser.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788971\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/8-1.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"ShellCheck reporting errors and warnings\" width=\"644\" height=\"365\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>ShellCheck also finds another issue, which isn\u2019t as serious. It is reported in green text. This indicates it is a warning, not an out-and-out error.<\/p>\n<p>Let\u2019s correct our error and replace the missing \u201c[.\u201d One bug-fix strategy is to correct the highest priority issues first and work down to the lower priority issues like warnings later.<\/p>\n<p>We replaced the missing \u201c[\u201d and ran ShellCheck once more.<\/p>\n<pre>shellcheck seasons.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788973\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/9-3.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Checking a script a second time with ShellCheck\" width=\"644\" height=\"230\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The only output from ShellCheck refers to our previous warning, so that\u2019s good. We have no high-priority issues needing fixing.<\/p>\n<p>The warning tells us that using the <code>read<\/code> command without the <code>-r<\/code> (read as-is) option will cause any backslashes in the input to be treated as escape characters. This is a good example of the type of pedantic output a linter can generate. In our case the user shouldn\u2019t be entering a backslash anyway\u2014we need them to enter a number.<\/p>\n<p>Warnings like this require a judgment call on the part of the programmer. Make the effort to fix it, or leave it as it is? It\u2019s a simple two-second fix. And it\u2019ll stop the warning cluttering up ShellCheck\u2019s output, so we might as well take its advice. We\u2019ll add an \u201cr\u201d to option the flags on the <code>read <\/code> command, and save the script.<\/p>\n<pre>read -pr \"Enter a month (1 to 12): \" month<\/pre>\n<p>Running ShellCheck once more gives us a clean bill of health.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-788975\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/02\/10-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"No errors or warnings reported by ShellCheck\" width=\"644\" height=\"75\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"ShellCheck_Is_Your_Friend\"><\/span>ShellCheck Is Your Friend<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>ShellCheck can detect, report, and advise on <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/koalaman\/shellcheck\/blob\/master\/README.md#gallery-of-bad-code\">a whole range of issues<\/a>.\u00a0Check out their <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/koalaman\/shellcheck\/blob\/master\/README.md#user-content-gallery-of-bad-code\">gallery of bad code<\/a>, which shows how many types of problems it can detect.<\/p>\n<p>It\u2019s free, fast, and takes a lot of the pain out of writing shell scripts. What\u2019s not to like?<\/p>\n<\/div>\n<p><script>\n setTimeout(function(){\n  !function(f,b,e,v,n,t,s)\n  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?\n  n.callMethod.apply(n,arguments):n.queue.push(arguments)};\n  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';\n  n.queue=[];t=b.createElement(e);t.async=!0;\n  t.src=v;s=b.getElementsByTagName(e)[0];\n  s.parentNode.insertBefore(t,s) } (window, document,'script',\n  'https:\/\/connect.facebook.net\/en_US\/fbevents.js');\n   fbq('init', '335401813750447');\n   fbq('track', 'PageView');\n  },3000);\n<\/script><\/p>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.howtogeek.com\/788955\/how-to-validate-the-syntax-of-a-linux-bash-script-before-running-it\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;How To Validate the Syntax of a Linux Bash Script Before Running It&#8221; fatmawati achmad zaenuri\/Shutterstock Bugs and typos in Linux Bash scripts can do dire things when the script is run. Here are some ways to check the syntax of your scripts before you even run them. Those Pesky Bugs Writing code is hard&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":428485,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/hero-1.png?height=200p&trim=2,2,2,2","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-428484","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/428484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=428484"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/428484\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/428485"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=428484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=428484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=428484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}