Sick Gaming
Using Square Brackets in Bash: Part 2 - Printable Version

+- Sick Gaming (https://www.sickgaming.net)
+-- Forum: Computers (https://www.sickgaming.net/forum-86.html)
+--- Forum: Linux, FreeBSD, and Unix types (https://www.sickgaming.net/forum-88.html)
+--- Thread: Using Square Brackets in Bash: Part 2 (/thread-89639.html)



Using Square Brackets in Bash: Part 2 - xSicKxBot - 04-04-2019

Using Square Brackets in Bash: Part 2

<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/04/using-square-brackets-in-bash-part-2.jpg" width="1010" height="574" title="" alt="" /></div><div><div><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/04/using-square-brackets-in-bash-part-2.jpg" class="ff-og-image-inserted"></div>
<p>Welcome back to our mini-series on square brackets. In the <a href="https://www.linux.com/blog/2019/3/using-square-brackets-bash-part-1">previous article</a>, we looked at various ways square brackets are used at the command line, including globbing. If you’ve not read that article, you might want to start there.</p>
<p>Square brackets can also be used as a command. Yep, for example, in:</p>
<pre>
[ "a" = "a" ]
</pre>
<p>which is, by the way, a valid command that you can execute,&nbsp;<code>[ ... ]</code> is a command. Notice that there are spaces between the opening bracket <code>[</code> and the parameters <code>"a" = "a"</code>, and then between the parameters and the closing bracket <code>]</code>. That is precisely because the brackets here act as a command, and you are separating the command from its parameters.</p>
<p>You would read the above line as “<i>test whether the string “a” is the same as string “a”</i>“. If the premise is true, the <code>[ ... ]</code> command finishes with an exit status of 0. If not, the exit status is 1. <a href="https://www.linux.com/blog/learn/2019/2/logical-ampersand-bash">We talked about exit statuses in a previous article</a>, and there you saw that you could access the value by checking the <code>$?</code> variable.</p>
<p>Try it out:</p>
<pre>
[ "a" = "a" ]
echo $?
</pre>
<p>And now try:</p>
<pre>
[ "a" = "b" ]
echo $?
</pre>
<p>In the first case, you will get a 0 (the premise is true), and running the second will give you a 1 (the premise is false). Remember that, in Bash, an exit status from a command that is 0 means it exited normally&nbsp;with no errors, and that makes it <code>true</code>. If there were any errors, the exit value would be a non-zero value (<code>false</code>). The <code>[ ... ]</code> command follows the same rules so that it is consistent with the rest of the other commands.</p>
<p>The <code>[ ... ]</code> command comes in handy in <code>if ... then</code> constructs and also in loops that require a certain condition to be met (or not) before exiting, like the <code>while</code> and <code>until</code> loops.</p>
<p>The logical operators for testing stuff are pretty straightforward:</p>
<pre>
<b>[ STRING1 = STRING2 ]</b> =&gt; checks to see if the strings are equal
<b>[ STRING1 != STRING2 ]</b> =&gt; checks to see if the strings are not equal <b>[ INTEGER1 -eq INTEGER2 ]</b> =&gt; checks to see if INTEGER1 is equal to INTEGER2 <b>[ INTEGER1 -ge INTEGER2 ]</b> =&gt; checks to see if INTEGER1 is greater than or equal to INTEGER2
<b>[ INTEGER1 -gt INTEGER2 ]</b> =&gt; checks to see if INTEGER1 is greater than INTEGER2
<b>[ INTEGER1 -le INTEGER2 ]</b> =&gt; checks to see if INTEGER1 is less than or equal to INTEGER2
<b>[ INTEGER1 -lt INTEGER2 ]</b> =&gt; checks to see if INTEGER1 is less than INTEGER2
<b>[ INTEGER1 -ne INTEGER2 ]</b> =&gt; checks to see if INTEGER1 is not equal to INTEGER2
etc...
</pre>
<p>You can also test for some very shell-specific things. The <code>-f</code> option, for example, tests whether a file exists or not:</p>
<pre>
for i in {000..099}; \ do \ if [ -f file$i ]; \ then \ echo file$i exists; \ else \ touch file$i; \ echo I made file$i; \ fi; \
done
</pre>
<p>If you run&nbsp;this in your test directory, line 3 will test to whether a file is in your long list of files. If it does exist, it will just print a message; but if it doesn’t exist, it will create it, to make sure the whole set is complete.</p>
<p>You could write the loop more compactly like this:</p>
<pre>
for i in {000..099};\
do\ if [ ! -f file$i ];\ then\ touch file$i;\ echo I made file$i;\ fi;\
done
</pre>
<p>The <code>!</code> modifier in the condition inverts the premise, thus line 3 would translate to “<i>if the file <code>file$i</code> does not exist</i>“.</p>
<p>Try it: delete some random files from the bunch you have in your test directory. Then run the loop shown above and watch how it rebuilds the list.</p>
<p>There are plenty of other tests you can try, including&nbsp;<code>-d</code> tests to see if the name belongs to a directory and <code>-h</code> tests to see if it is a symbolic link. You can also test whether a files belongs to a certain group of users (<code>-G</code>), whether one file is older than another (<code>-ot</code>), or even whether a file contains something or is, on the other hand, empty.</p>
<p>Try the following for example. Add some content to some of your files:</p>
<pre>
echo "Hello World" &gt;&gt; file023
echo "This is a message" &gt;&gt; file065
echo "To humanity" &gt;&gt; file010
</pre>
<p>and then run this:</p>
<pre>
for i in {000..099};\
do\ if [ ! -s file$i ];\ then\ rm file$i;\ echo I removed file$i;\ fi;\
done
</pre>
<p>And you’ll remove all the files that are empty, leaving only the ones you added content to.</p>
<p>To find out more, check the manual page for the <code>test</code> command (a synonym for <code>[ ... ]</code>) with <code>man test</code>.</p>
<p>You may also see double brackets (<code>[[ ... ]]</code>) sometimes used in a similar way to single brackets. The reason for this is because double brackets give you a wider range of comparison operators. You can use <code>==</code>, for example, to compare a string to a pattern instead of just another string; or &lt; and <code>&gt;</code> to test whether a string would come before or after another in a dictionary.</p>
<p>To find out more about extended operators <a href="https://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions">check out this full list of Bash expressions</a>.</p>
<h3>Next Time</h3>
<p>In an upcoming article, we’ll continue our tour and take a look at the role of parentheses <code>()</code> in Linux command lines. See you then!</p>
<p><em>Read more:</em></p>
<ol>
<li><a href="https://www.linux.com/blog/learn/2019/1/linux-tools-meaning-dot">The Meaning of Dot (<code>.</code>)</a></li>
<li><a href="https://www.linux.com/blog/learn/2019/1/understanding-angle-brackets-bash">Understanding Angle Brackets in Bash (<code>&lt;...&gt;</code>)</a></li>
<li><a href="https://www.linux.com/blog/learn/2019/1/more-about-angle-brackets-bash">More About Angle Brackets in Bash(<code>&lt;</code> and <code>&gt;</code>)</a></li>
<li><a href="https://www.linux.com/blog/learn/2019/2/and-ampersand-and-linux">And, Ampersand, and &amp; in Linux (<code>&amp;</code>)</a></li>
<li><a href="https://www.linux.com/blog/learn/2019/2/ampersands-and-file-descriptors-bash">Ampersands and File Descriptors in Bash (<code>&amp;</code>)</a></li>
<li><a href="https://www.linux.com/blog/learn/2019/2/logical-ampersand-bash">Logical &amp; in Bash (<code>&amp;</code>)</a></li>
<li><a href="https://www.linux.com/blog/learn/2019/2/all-about-curly-braces-bash">All about {Curly Braces} in Bash (<code>{}</code>)</a></li>
<li><a href="https://www.linux.com/blog/2019/3/using-square-brackets-bash-part-1">Using Square Brackets in Bash: Part 1</a></li>
</ol>
</div>