Home Learn Linux Bash test command explained with examples

Bash test command explained with examples

by Pulkit Chandak
test command bash

Comparison and checking might not be suitable in real life, but it is essential in programming. It helps to ensure that you have good code that interacts well and works as expected. Comparison of various values, checking of the different properties of files, and logical reasoning with and/or methods is a massive part of any programming language and the entire basis of reasoning within any script’s framework. For Bash, the command test provides many of these features, and as we will see, an even more simplified version of that also exists. So let us know what it is all about.

Bash test command introduction

The manual page of the test quite states, “check file types and compare values,” which encloses a plethora of features. To give an overview, we use a test to compare numbers, if they are equal or greater/smaller. We use it to check whether two strings are similar or not and to see if a string is empty. We use it to check file types and permissions and to check for their existence. For such a versatile command, the test has a pretty straightforward syntax.

Return messages

One important thing to understand before learning the command is that the test command, by default, doesn’t have a return message. It ends with an exit code of 1 or 0, but we can’t see it if we do it on the command line. For example, if we enter a command to check if 1 is equal to 2:

test 1 -eq 2

Running this command as is doesn’t return a message. So we add a bit of code to return a message:

test 1 -eq 2 && echo "true" || echo "false"

If the comparison is true, this will return a string that says  “true”. If not, it will return “false”.

Simple test command

Simple test command

This works because, in Bash, the “&&” token can be used to execute a message if the previous command is executed successfully and, where applicable, has a positive result. This means that if the result of our comparison is true, the first part next to the “&&” will be executed. On the other hand, the token “||” is executed when only when the first command is a failure. This was the case here, and this is the result that we saw.

Shortened format

This command has to frequently be used in bash that even a shortened form of this was created. To enter the same command as the case above, you can simply write:

[ 1 -eq 2 ] && echo "true" || echo "false"

It is essential to note the presence of a single space right after the opening square bracket and right before the closing one. The absence of those spaces results in a situation where Bash cannot recognize the syntax because the command becomes “[1”, which means nothing.

Shortened test command

Shortened test command

This doesn’t look like a drastic change in just one line, but in larger scripts, this makes a lot of difference for the performance and readability.

There are three significant categories of test commands:

Integer tests

Integer tests are the ones that are used to compare different integers, like which one is higher/lower or if they are equal. There are various combinations of these comparisons, which can be tested in a straightforward form. Given that int1 and int2 are the two integers that need to be compared, the expressions look like this:

Greater than
test int1 -gt int2 && echo "true" || echo "false"

Or

[ int1 -gt int2 ] && echo "true" || echo "false"

If int1 has a higher value than int2, the command with return “true”. If not, it will return “false”.

Less than
test int1 -lt int2 && echo "true" || echo "false"

Or

[ int1 -lt int2 ] && echo "true" || echo "false"

If int1 has a lower value than int2, the command with return “true”. If not, it will return “false”.

Equal to
test int1 -eq int2 && echo "true" || echo "false"

Or

[ int1 -eq int2 ] && echo "true" || echo "false"

If int1 and int2 have the same value, the command with return “true”. If not, it will return “false”.

Not equal to
test int1 -ne int2 && echo "true" || echo "false"

Or

[ int1 -ne int2 ] && echo "true" || echo "false"

If int1 and int2 don’t have the same value, the command with return “true”. If not, it will return “false”.

Greater than or equal to
test int1 -ge int2 && echo "true" || echo "false"

Or

[ int1 -ge int2 ] && echo "true" || echo "false"

If int1 has a value higher than int2 or is equal to int2, the command with return “true”. If not, it will return “false”.

Less than or equal to
test int1 -le int2 && echo "true" || echo "false"

Or

[int1 -le int2] && echo "true" || echo "false"

If int1 has a value lower than int2 or is equal to int2, the command with return “true”. If not, it will return “false”.

Integer tests

Integer tests

String tests

Strings are any set of characters put in a sequence. They might even all be integral characters, but defined as a string. You can define any set of a random set of characters as a string, as long as it doesn’t mess with Bash’s syntax rules. There are often cases where we need to compare strings or check for their validity. Assuming the strings as str1 and str2 (in case of a comparison), the tests look like this:

Non-zero string
test -n "str1" && echo "true" || echo "false"

Or

[ -n "str1" ] && echo "true" || echo "false"

If the string is not empty, meaning it has anything inside the double quotations, it will return “true”. Otherwise, it will return “false”.

Zero string
test -z "str1" && echo "true" || echo "false"

Or

[ -z "str1" ] && echo "true" || echo "false"

If the string is empty, meaning it has nothing inside the double quotations, it will return “true”. Otherwise, it will return “false”.

Equal strings
test "str1" = "str2" && echo "true" || echo "false"

Or

[ "str1" = "str2" ] && echo "true" || echo "false"

If both str1 and str2 are precisely the same, only then will the result will be “true”. Even a difference in an uppercase alphabet qualifies for inequality. Otherwise, the result will be “false”.

Unequal strings
test "str1" != "str2" && echo "true" || echo "false"

Or

[ "str1" != "str2" ] && echo "true" || echo "false"

If both str1 and str2 are not precisely the same, only then will the result will be “true”. Otherwise, the result will be “false”.

Tests on strings

Tests on strings

File tests

The cases of integers and strings are significant when taking in specific sections containing said integers or strings. But in the case of Bash, we will have to deal with files quite a lot. So if the file is file1 and file2 (in case of comparisons), the commands look like this:

Linked files

Inode number can be considered an identification number associated with each file on a Linux system. It is the property that makes every file unique. Now, if you want to check if two files have the same Inode numbers, that is, they are the same file, you can use the following command:

test file1 -ef file2 && echo "true" || echo "false"

Or

[ file1 -ef file2 ]&& echo "true" || echo "false"

But now you might be thinking, how are two files the same? Even if you were to create copies of a file, it would be a completely different file in itself. Well, it doesn’t have to do with duplicated files as much as it has to do with files that are linked. Linux provides an option for soft-linking files to create a file that links to another file. So if file1 is symlinked (soft linked) to file2, then file2 is nothing on its own, just an empty shell that refers to file1 for the content. In that case, the comparison turns out to be “true”.

Linked files test

Linked files test

Newer file
test file1 -nt file2 && echo "true" || echo "false"

Or

[ file1 -nt file2 ] && echo "true" || echo "false"

This is simple enough. If file1 is newer than file2, the result is “true”; otherwise, it is “false”.

Older file
test file1 -ot file2 && echo "true" || echo "false"

Or

[ file1 -ot file2 ] && echo "true" || echo "false"

If file1 is older than file2, the result is “true”; otherwise, it is “false”.

Files age comparison

Files age comparison

Existence and nature of the file
test -e file1 && echo "true" || echo "false"

Or

[ -e file1 ] && echo "true" || echo "false"

Yes, you can indeed check if a file even exists or not. All the other file-related tests first check whether the file exists. Only if it does, the test proceeds.

test -s file1 && echo "true" || echo "false"

Or

[ -s file1 ] && echo "true" || echo "false"

For a  slight variation, this checks whether a file exists or not and, if it does, if it is empty or not, that is, if it has a size greater than zero or not.

test -f file1 && echo "true" || echo "false"

Or

[ -f file1 ] && echo "true" || echo "false"

This checks whether or not the file exists, and if it does, it is a regular file. The other case would be that it is a directory, in which the answer becomes “false”.

test -d file1 && echo "true" || echo "false"

Or

[ -d file1 ] && echo "true" || echo "false"

This check if the file exists and if it is a directory. If so, “true” will be returned. If not, “false”.

test -h file1 && echo "true" || echo "false"

Or

[ -h file1 ] && echo "true" || echo "false"

This one checks if the file is a symbolic link, the concept of which we just explained. If so, “true” will be returned. If not, “false”.

Nature and type of a file

Nature and type of a file

File permissions

There are three standard file permissions, which can all be tested through the test command: read, write and execute.

test -r file1 && echo "true" || echo "false"

Or

[ -r file1 ] && echo "true" || echo "false"

Checks if the file exists and can be read by the user.

test -w file1 && echo "true" || echo "false"

Or

[ -w file1 ] && echo "true" || echo "false"

Checks if the file exists and can be written/edited by the user.

test -x file1 && echo "true" || echo "false"

Or

[ -x file1 ] && echo "true" || echo "false"

Checks if the file exists and can be executed by the user.

File permissions tests

File permissions tests

There are many more variations of this command, including checking for block-special files, character-special files, sockets, etc. This can be checked using the man command:

man help

Conclusion

The help command, as we have just seen, is essential to ensure certain critical factors for creating specific programs. It provides and confirms things on a scale required by almost everything one may need. We hope that this article was helpful. Cheers!

You may also like

Leave a Comment

fl_logo_v3_footer

ENHANCE YOUR LINUX EXPERIENCE.



FOSS Linux is a leading resource for Linux enthusiasts and professionals alike. With a focus on providing the best Linux tutorials, open-source apps, news, and reviews written by team of expert authors. FOSS Linux is the go-to source for all things Linux.

Whether you’re a beginner or an experienced user, FOSS Linux has something for everyone.

Follow Us

Subscribe

©2016-2023 FOSS LINUX

A PART OF VIBRANT LEAF MEDIA COMPANY.

ALL RIGHTS RESERVED.

“Linux” is the registered trademark by Linus Torvalds in the U.S. and other countries.