{"id":384006,"date":"2021-12-20T17:00:47","date_gmt":"2021-12-20T14:00:47","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-use-double-bracket-conditional-tests-in-linux\/"},"modified":"2021-12-20T17:00:47","modified_gmt":"2021-12-20T14:00:47","slug":"how-to-use-double-bracket-conditional-tests-in-linux","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-use-double-bracket-conditional-tests-in-linux\/","title":{"rendered":"#How to Use Double Bracket Conditional Tests in Linux"},"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-6a36f952e7224\" 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-6a36f952e7224\" 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-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-double-bracket-conditional-tests-in-linux\/#Single_and_Double_Brackets\" >Single and Double Brackets<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-double-bracket-conditional-tests-in-linux\/#Builtins_and_Keywords\" >Builtins and Keywords<\/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-use-double-bracket-conditional-tests-in-linux\/#Shell_Globbing\" >Shell Globbing<\/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-use-double-bracket-conditional-tests-in-linux\/#Quoting_Strings\" >Quoting Strings<\/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-use-double-bracket-conditional-tests-in-linux\/#Filename_Globbing_Gotchas\" >Filename Globbing Gotchas<\/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-use-double-bracket-conditional-tests-in-linux\/#Logical_AND_and_OR\" >Logical AND and OR<\/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-use-double-bracket-conditional-tests-in-linux\/#Regexes\" >Regexes<\/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-use-double-bracket-conditional-tests-in-linux\/#Just_One_Condition\" >Just One Condition<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How to Use Double Bracket Conditional Tests in Linux&#8221;<\/strong><\/p>\n<div>\n<figure style=\"width: 1200px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage size-full wp-image-770699\" data-pagespeed-lazy-srcset=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/shutterstock_1278851809.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\/shutterstock_1278851809.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\/shutterstock_1278851809.png?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" 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\">fatmawati achmad zaenuri\/Shutterstock.com<\/span><\/figcaption><\/figure>\n<p>Conditional tests branch the flow of execution of 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 according to the result of a logical expression. Double bracket conditional tests simplify the syntax considerably\u2014but still have their own gotchas.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Single_and_Double_Brackets\"><\/span>Single and Double Brackets<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Bash provides the <code>test<\/code> command. This lets you test logical expressions. The expression will return an answer that indicates a true or false response. A true response is indicated by a return value of zero. Anything other than zero indicates false.<\/p>\n<p>Chaining commands on the command line with the <code>&amp;&amp;<\/code> operator uses this feature. Commands are only executed if the previous command completes successfully.<\/p>\n<p>If the test is true, the word \u201cYes\u201d will be printed.<\/p>\n<pre>test 15 -eq 15 &amp;&amp; echo \"Yes\"<\/pre>\n<pre>test 14 -eq 15 &amp;&amp; echo \"Yes\"<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770676\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/1-3.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Simple examples of the Bash test command\" width=\"644\" height=\"110\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The single bracket conditional tests mimic the <code>test<\/code> command. They wrap the expression in brackets \u201c<code>[ ]<\/code>\u201d and operate just like the <code>test<\/code> command. In fact, they\u2019re the same program, created from the same source code. The only operational difference is how the <code>test<\/code> version and the <code>[<\/code> version handle help requests.<\/p>\n<p>This is from the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/coreutils\/coreutils\/blob\/master\/src\/test.c\">source code<\/a>:<\/p>\n<pre>\/* Recognize --help or --version, but only when invoked in the&#13;\n\"[\" form, when the last argument is not \"]\". Use direct&#13;\nparsing, rather than parse_long_options, to avoid accepting&#13;\nabbreviations. POSIX allows \"[ --help\" and \"[ --version\" to&#13;\nhave the usual GNU behavior, but it requires \"test --help\"&#13;\nand \"test --version\" to exit silently with status 0. *\/<\/pre>\n<p>We can see the effect of this by asking <code>test<\/code> and <code>[<\/code> for help and checking the response code sent to Bash.<\/p>\n<pre>test --help<\/pre>\n<pre>echo $?<\/pre>\n<pre>[ --help<\/pre>\n<pre>echo $?<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770677\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/3-3.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Using --help on test and [\" width=\"644\" height=\"190\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Both <code>test<\/code> and <code>[<\/code> are shell <em>builtins<\/em>, meaning they are baked right into Bash. But there\u2019s also a standalone binary version of <code>[<\/code> .<\/p>\n<pre>type test<\/pre>\n<pre>type [<\/pre>\n<pre>whereis [<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770678\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/2-4.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Finding the different types of [ and test commands\" 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>By contrast, the double bracket conditional tests <code>[[<\/code> and <code>]]<\/code> are <em>keywords<\/em>. <code>[[<\/code> and <code>]]<\/code> also perform logical tests, but their syntax is different. Because they\u2019re keywords, you can use some neat features that won\u2019t work in the single bracket version.<\/p>\n<p>The double bracket keywords are supported by Bash, but they\u2019re not available in every other shell. For example, the Korn shell does support them, but the plain old shell, sh, doesn\u2019t. All of our scripts start with the line:<\/p>\n<pre>#!\/bin\/bash<\/pre>\n<p>This ensures we\u2019re calling the Bash shell to run the script.<\/p>\n<p><strong>RELATED:<\/strong> <strong><em>How to Create and Run Bash Shell Scripts on Windows 10<\/em><\/strong><\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Builtins_and_Keywords\"><\/span>Builtins and Keywords<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We can use the <code>compgen<\/code> program to list the builtins:<\/p>\n<pre>compgen -b | fmt -w 70<\/pre>\n<p>Without piping the output through <code>fmt<\/code> we\u2019d get a long list with each builtin on its own line. It\u2019s more convenient in this instance to see the builtins grouped together into a paragraph.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770679\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/4-3.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Listing the Bash builtins\" width=\"644\" height=\"190\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>We can see <code>test<\/code> and <code>[<\/code> in the list, but <code>]<\/code> isn\u2019t listed. The <code>[<\/code> command looks for a closing <code>]<\/code> to detect when it has reached the end of the expression, but <code>]<\/code> is not a separate builtin. It\u2019s just a signal we give to <code>[<\/code> to indicate the end of the parameter list.<\/p>\n<p>To see the keywords, we can use:<\/p>\n<pre>compgen -k | fmt -w 70<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770680\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/5-3.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Listing the Bash keywords\" width=\"644\" height=\"110\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The <code>[[<\/code> and <code>]]<\/code> keywords are both in the list, because <code>[[<\/code> is a one keyword and <code>]]<\/code> is another. They are a matched pair, just like <code>if<\/code> and <code>fi<\/code> , and <code>case<\/code> and <code>esac<\/code> .<\/p>\n<p>When Bash is parsing a script\u2014or a command line\u2014and detects a keyword that has a matching, closing keyword it gathers everything that appears between them and applies whatever special treatment the keywords support.<\/p>\n<p>With a builtin, what follows the builtin command is passed to it exactly like parameters to any other command-line program. This means special care has to be taken by the author of the script regarding such things as spaces in variable values.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Shell_Globbing\"><\/span>Shell Globbing<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Double bracket conditional tests can make use of shell globbing. This means the asterisk \u201c<code>*<\/code>\u201d will expand to mean \u201canything.\u201d<\/p>\n<p>Type or copy the following text into an editor and save it to a file called \u201cwhelkie.sh.\u201d<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nstringvar=\"Whelkie Brookes\"&#13;\n&#13;\nif [[ \"$stringvar\" == *elk* ]];&#13;\nthen&#13;\n  echo \"Warning contains seafood\"&#13;\nelse&#13;\n  echo \"Free from molluscs\"&#13;\nfi<\/pre>\n<p>To make the script executable we\u2019ll need to use the <code>chmod<\/code> command with the <code>-x<\/code>\u00a0(execute) option. You\u2019ll need to do this to all of the scripts in this article if you want to try them out.<\/p>\n<pre>chmod +x whelkie.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770681\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/16-1.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Using chmod to make a script executable\" 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>When we run the script we see the string \u201celk\u201d was found in the string \u201cWhelkie\u201d, regardless of what other characters surround it.<\/p>\n<pre>.\/whelkie.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770682\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/6-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the whelkie.sh script\" width=\"644\" height=\"95\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>One point to note is that we don\u2019t wrap the search string in double quotes. If you do, the globbing won\u2019t happen. The search string will be treated literally.<\/p>\n<p>Other forms of shell globbing are allowed. The question mark \u201c<code>?<\/code>\u201d will match single characters, and single square brackets are used to indicate ranges of characters. For example, if you don\u2019t know which case to use, you can cover both eventualities with a range.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nstringvar=\"Jean-Claude van Clam\"&#13;\n&#13;\nif [[ \"$stringvar\" == *[cC]lam* ]];&#13;\nthen&#13;\n  echo \"Warning contains seafood.\"&#13;\nelse&#13;\n  echo \"Free from molluscs.\"&#13;\nfi<\/pre>\n<p>Save this script as \u201cdamme.sh\u201d and make it executable. When we run it the conditional statement resolves to true, and the first clause of the if statement is executed.<\/p>\n<pre>.\/damme.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770683\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/7-3.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the damme.sh script\" width=\"644\" height=\"95\" 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=\"Quoting_Strings\"><\/span>Quoting Strings<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We mentioned wrapping strings in double quotes earlier. If you do, shell globbing won\u2019t occur. Although convention says it is good practice, you don\u2019t <em>need<\/em> to wrap string variables in quotes when using <code>[[<\/code> and <code>]]<\/code>even if they contain spaces. Look at the next example. Both the <code>$stringvar<\/code> and <code>$surname<\/code> string variables contain spaces, but neither one is quoted in the conditional statement.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nstringvar=\"van Damme\"&#13;\nsurname=\"van Damme\"&#13;\n&#13;\nif [[ $stringvar == $surname ]];&#13;\nthen&#13;\necho \"Surnames match.\"&#13;\nelse&#13;\necho \"Surnames don't match.\"&#13;\nfi<\/pre>\n<p>Save this into a file called \u201csurname.sh\u201d and make it executable. Run it using:<\/p>\n<pre>.\/surname.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770684\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/8-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the surname.sh script\" width=\"644\" height=\"95\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Despite both strings containing spaces, the script succeeds and the conditional statement resolves to true. This is useful when dealing with paths and directory names that contain spaces. Here, the <code>-d<\/code> option returns true if the variable contains a valid directory name.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\ndir=\"\/home\/dave\/Documents\/Needs Work\"&#13;\n&#13;\nif [[ -d ${dir} ]];&#13;\nthen&#13;\n  echo \"Directory confirmed\"&#13;\nelse&#13;\n  echo \"Directory not found\"&#13;\nfi<\/pre>\n<p>If you change the path in the script to reflect a directory on your own computer, save the text into a file called \u201cdir.sh\u201d and make it executable, you can see that this works.<\/p>\n<pre>.\/dir.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770685\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/9-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the dir.sh script\" width=\"644\" height=\"95\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p><strong>RELATED:<\/strong> <strong><em>How to Work with Variables in Bash<\/em><\/strong><\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Filename_Globbing_Gotchas\"><\/span>Filename Globbing Gotchas<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>An interesting difference between <code>[ ]<\/code> and <code>[[ ]]<\/code> relates to file names with globbing in them. The form \u201c*.sh\u201d will match all script files. Using single brackets <code>[ ]<\/code>\u00a0fails unless there is a single script file. Finding more than one script throws an error.<\/p>\n<p>Here\u2019s the script with single bracket conditionals.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nif [ -a *.sh ];&#13;\nthen&#13;\n  echo \"Found a script file\"&#13;\nelse&#13;\n  echo \"Didn't find a script file\"&#13;\nfi<\/pre>\n<p>We saved this text into \u201cscript.sh\u201d and made it executable. We checked how many scripts were in the directory, then ran the script.<\/p>\n<pre>ls<\/pre>\n<pre>.\/script.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770686\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/10-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the script.sh script\" width=\"644\" height=\"150\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Bash throws an error. We removed all but one script file and ran the script again.<\/p>\n<pre>ls<\/pre>\n<pre>.\/script.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770687\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/11-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the script.sh script with a single script in the directory\" width=\"644\" height=\"130\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The conditional test returns true and the script doesn\u2019t cause an error. Editing the script to use double brackets provides a third type of behavior.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nif [[ -a *.sh ]];&#13;\nthen&#13;\n  echo \"Found a script file\"&#13;\nelse&#13;\n  echo \"Didn't find a script file\"&#13;\nfi<\/pre>\n<p>We saved this into a file called \u201cdscript.sh\u201d and made it executable. Running this script in a directory with many scripts in it doesn\u2019t throw an error, but the script fails to recognize any script files.<\/p>\n<p>The conditional statement using double brackets only resolves to true in the unlikely case that you have a file actually called \u201c*.sh\u201d in the directory.<\/p>\n<pre>.\/dscript.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770688\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/12-1.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the dscript.sh script\" 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<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Logical_AND_and_OR\"><\/span>Logical AND and OR<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Double brackets let you use <code>&amp;&amp;<\/code> and <code>||<\/code> as the logical AND and OR operators.<\/p>\n<p>This script should resolve the conditional statement to true because 10 does equal 10 <em>and<\/em> 25 is less than 26.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nfirst=10&#13;\nsecond=25&#13;\n&#13;\nif [[ first -eq 10 &amp;&amp; second -lt 26 ]];&#13;\nthen&#13;\n  echo \"Condition met\"&#13;\nelse&#13;\n  echo \"Condition failed\"&#13;\nfi<\/pre>\n<p>Save this text into a file called \u201cand.sh\u201d, make it executable, and run it with:<\/p>\n<pre>.\/and.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770689\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/13-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the and.sh script\" width=\"644\" height=\"95\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The script executes as we\u2019d expect.<\/p>\n<p>This time we\u2019ll use the <code>||<\/code> operator. The conditional statement should resolve to true because although 10 is not greater than 15, 25 is still less than 26. As long as either the first comparison <em>or<\/em> the second comparison is true, the conditional statement as a whole resolves to true.<\/p>\n<p>Save this text as \u201cor.sh\u201d and make it executable.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nfirst=10&#13;\nsecond=25&#13;\n&#13;\nif [[ first -gt 15 || second -lt 26 ]];&#13;\nthen&#13;\n  echo \"Condition met.\"&#13;\nelse&#13;\n  echo \"Condition failed.\"&#13;\nfi<\/pre>\n<pre>.\/or.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-770690 size-full\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/14-2.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the or.sh script\" width=\"644\" height=\"95\" 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=\"Regexes\"><\/span>Regexes<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Double bracket conditional statements permit the use of the <code>=~<\/code> operator, which applies the regex search patterns in a string to the other half of the statement. If the regex is satisfied the conditional statement is considered to be true. If the regex finds no matches the conditional statement resolves to false.<\/p>\n<p><strong>RELATED:<\/strong> <strong><em>How to Use Regular Expressions (regexes) on Linux<\/em><\/strong><\/p>\n<p>Save this text to a file called \u201cregex.sh\u201d, and make it executable.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\nwords=\"one two three\"&#13;\nWordsandNumbers=\"one 1 two 2 three 3\"&#13;\nemail=\"dave@fabricateddomain.co.uk\"&#13;\n&#13;\nmask1=\"[0-9]\"&#13;\nmask2=\"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}\"&#13;\n&#13;\nif [[ $words =~ $mask1 ]];&#13;\nthen&#13;\n  echo \"\"$words\" contains digits.\"&#13;\nelse&#13;\n  echo \"No digits found in \"$words\".\"&#13;\nfi&#13;\n&#13;\nif [[ $WordsandNumbers =~ $mask1 ]];&#13;\nthen&#13;\n  echo \"\"$WordsandNumbers\" contains digits.\"&#13;\nelse&#13;\n  echo \"No digits found in \"$WordsandNumbers\".\"&#13;\nfi&#13;\n&#13;\nif [[ $email =~ $mask2 ]];&#13;\nthen&#13;\n  echo \"\"$email\" is a valid e-mail address.\"&#13;\nelse&#13;\n  echo \"Couldn't parse \"$email\".\"&#13;\nfi<\/pre>\n<p>The first set of double brackets uses the string variable <code>$mask1<\/code> as the regex. This contains the pattern for all digits in the range of zero to nine. It applies this regex to the <code>$words<\/code> string variable.<\/p>\n<p>The second set of double brackets again uses the string variable <code>$mask1<\/code> as the regex, but this time it uses it with the <code>$WordsandNumbers<\/code> string variable.<\/p>\n<p>The last set of double brackets uses a more complex regex mask in string variable <code>$mask2<\/code> .<\/p>\n<ul>\n<li><strong>[A-Za-z0-9._%+-]+<\/strong>: This matches any character that is an uppercase or lowercase letter, or any digit from zero to nine, or a period, underscore, percentage sign, or plus or minus sign. The \u201c<code>+<\/code>\u201d outside of the \u201c<code>[]<\/code>\u201d means repeat those matches for as many characters as it finds.<\/li>\n<li><strong>@<\/strong>: This matches the \u201c@\u201d character only.<\/li>\n<li><strong>[A-Za-z0-9.-]+<\/strong>: This matches any character that is an uppercase or lowercase letter, or any digit from zero to nine, or a period or hyphen. The \u201c<code>+<\/code>\u201d outside of the \u201c<code>[ ]<\/code>\u201d means repeat those matches for as many characters as it finds.<\/li>\n<li><strong>.<\/strong>: This matches the \u201c.\u201d character only.<\/li>\n<li><strong>[A-Za-z]{2,4}<\/strong>: This matches any uppercase or lowercase letter. The \u201c<code>{2,4}<\/code>\u201d means match at least two characters, and at most four.<\/li>\n<\/ul>\n<p>Putting that all together, the regex mask will check whether an email address is correctly formed.<\/p>\n<p>Save the script text into a file called \u201cregex.sh\u201d and make it executable. When we run the script we get this output.<\/p>\n<pre>.\/regex.sh<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-770691\" data-pagespeed-lazy-src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/15-1.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Running the regex.sh script\" width=\"644\" height=\"130\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The first conditional statement fails because the regex is looking for digits but there are no digits in the value held in the <code>$words<\/code> string variable.<\/p>\n<p>The second conditional statement succeeds because the <code>$WordsandNumbers<\/code> string variable does contain digits.<\/p>\n<p>The final conditional statement succeeds\u2014that is, it resolves to true\u2014because the email address is properly formatted.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Just_One_Condition\"><\/span>Just One Condition<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Double bracket conditional tests bring flexibility and legibility to your scripts. Just being able to use regexes in your conditional tests justifies learning how to use <code>[[<\/code> and <code>]]<\/code>.<\/p>\n<p>Just make sure the script calls a shell that supports them, like Bash.<\/p>\n<p><strong>RELATED:<\/strong> <strong><em>15 Special Characters You Need to Know for Bash<\/em><\/strong><\/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\/770617\/how-to-use-double-bracket-conditional-tests-in-linux\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How to Use Double Bracket Conditional Tests in Linux&#8221; fatmawati achmad zaenuri\/Shutterstock.com Conditional tests branch the flow of execution of Linux Bash scripts according to the result of a logical expression. Double bracket conditional tests simplify the syntax considerably\u2014but still have their own gotchas. Single and Double Brackets Bash provides the test command. This lets&#8230;<\/p>\n","protected":false},"author":1,"featured_media":384007,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2021\/11\/shutterstock_1278851809.png?height=200p&trim=2,2,2,2","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-384006","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\/384006","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=384006"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/384006\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/384007"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=384006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=384006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=384006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}