Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using Square Brackets in Bash: Part 2
1
Using Square Brackets in Bash: Part 2

[Image: using-square-brackets-in-bash-part-2.jpg]

[Image: using-square-brackets-in-bash-part-2.jpg]

Welcome back to our mini-series on square brackets. In the previous article, 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.

Square brackets can also be used as a command. Yep, for example, in:

Code:
[ "a" = "a" ]

which is, by the way, a valid command that you can execute, 
Code:
[ ... ]
is a command. Notice that there are spaces between the opening bracket
Code:
[
and the parameters
Code:
"a" = "a"
, and then between the parameters and the closing bracket
Code:
]
. That is precisely because the brackets here act as a command, and you are separating the command from its parameters.

You would read the above line as “test whether the string “a” is the same as string “a”“. If the premise is true, the
Code:
[ ... ]
command finishes with an exit status of 0. If not, the exit status is 1. We talked about exit statuses in a previous article, and there you saw that you could access the value by checking the
Code:
$?
variable.

Try it out:

Code:
[ "a" = "a" ] echo $?

And now try:

Code:
[ "a" = "b" ] echo $?

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 with no errors, and that makes it
Code:
true
. If there were any errors, the exit value would be a non-zero value (
Code:
false
). The
Code:
[ ... ]
command follows the same rules so that it is consistent with the rest of the other commands.

The
Code:
[ ... ]
command comes in handy in
Code:
if ... then
constructs and also in loops that require a certain condition to be met (or not) before exiting, like the
Code:
while
and
Code:
until
loops.

The logical operators for testing stuff are pretty straightforward:

Code:
[ STRING1 = STRING2 ] => checks to see if the strings are equal [ STRING1 != STRING2 ] => checks to see if the strings are not equal [ INTEGER1 -eq INTEGER2 ] => checks to see if INTEGER1 is equal to INTEGER2 [ INTEGER1 -ge INTEGER2 ] => checks to see if INTEGER1 is greater than or equal to INTEGER2 [ INTEGER1 -gt INTEGER2 ] => checks to see if INTEGER1 is greater than INTEGER2 [ INTEGER1 -le INTEGER2 ] => checks to see if INTEGER1 is less than or equal to INTEGER2 [ INTEGER1 -lt INTEGER2 ] => checks to see if INTEGER1 is less than INTEGER2 [ INTEGER1 -ne INTEGER2 ] => checks to see if INTEGER1 is not equal to INTEGER2 etc...

You can also test for some very shell-specific things. The
Code:
-f
option, for example, tests whether a file exists or not:

Code:
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

If you run 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.

You could write the loop more compactly like this:

Code:
for i in {000..099};\ do\ if [ ! -f file$i ];\ then\ touch file$i;\ echo I made file$i;\ fi;\ done

The
Code:
!
modifier in the condition inverts the premise, thus line 3 would translate to “if the file
Code:
file$i
does not exist
“.

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.

There are plenty of other tests you can try, including 
Code:
-d
tests to see if the name belongs to a directory and
Code:
-h
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
), whether one file is older than another (
Code:
-ot
), or even whether a file contains something or is, on the other hand, empty.

Try the following for example. Add some content to some of your files:

Code:
echo "Hello World" >> file023 echo "This is a message" >> file065 echo "To humanity" >> file010

and then run this:

Code:
for i in {000..099};\ do\ if [ ! -s file$i ];\ then\ rm file$i;\ echo I removed file$i;\ fi;\ done

And you’ll remove all the files that are empty, leaving only the ones you added content to.

To find out more, check the manual page for the
Code:
test
command (a synonym for
Code:
[ ... ]
) with
Code:
man test
.

You may also see double brackets (
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:
==
, for example, to compare a string to a pattern instead of just another string; or < and
Code:
>
to test whether a string would come before or after another in a dictionary.

To find out more about extended operators check out this full list of Bash expressions.

Next Time

In an upcoming article, we’ll continue our tour and take a look at the role of parentheses
Code:
()
in Linux command lines. See you then!

Read more:

  1. The Meaning of Dot (
    Code:
    .
    )


  2. Understanding Angle Brackets in Bash (
    Code:
    <...>
    )


  3. More About Angle Brackets in Bash(
    Code:
    <
    and
    Code:
    >
    )


  4. And, Ampersand, and & in Linux (
    Code:
    &
    )


  5. Ampersands and File Descriptors in Bash (
    Code:
    &
    )


  6. Logical & in Bash (
    Code:
    &
    )


  7. All about {Curly Braces} in Bash (
    Code:
    {}
    )


  8. Using Square Brackets in Bash: Part 1
Reply



Forum Jump:


Users browsing this thread: 1 Guest(s)