Operator test in a conditional


I'm starting to make simple scripts in Linux, and I have a doubt when sending parameters to one. The script is as follows:

if test $1 -lt $2
            echo "La cadena 1 es menor que la cadena 2"
            echo "Las cadenas son iguales"

The question is that if I take the test % I get an error not such file or directory , and I'm not sure that putting test is appropriate.

asked by Carlos Gargallo 25.07.2017 в 14:40

2 answers


test is a command and serves to validate what comes next. It is usually represented by its synonym sibling [ which allows you to change the syntax to something more visually clear:

if test expresión_booleana


if [ expresión_booleana ]

Or also (as indicated by the manual or Alvaro in your excellent answer ):

if [[  expresión_booleana ]]

The idea, then, is that all three methods receive a boolean expression that is then evaluated to reach the then or the else , etc. Therefore, what you should write is something like:

if [ "$1" -lt "$2" ]

You have more information in the Bash Reference Manual → 4.1. Bourne Shell Builtins (yes, you are in KSH but the reference is equivalent).

Regarding why it does not work if you remove the word test , you should bear in mind that what results is:

if $1 -lt $2

that is not a valid expression, since if needs to be expressed in the form:

if test-commands; then
[elif more-test-commands; then
[else alternate-consequents;]

What you are really doing is trying to execute the command:

tu_primer_parametro -lt tu_segundo_parametro

So it looks for the binary tu_primer_parametro in all directories of $PATH as, logically, it does not find it, says "not such file or directory".
You can play it saying:

touch /tmp/hola
if /tmp/hola -lt 2; then echo "fichero encontrado"; else echo "no encontrado"; fi

Here you will surely get an error of this type, because /tmp/hola will not be an executable file:

ksh: /tmp/hola: cannot execute [Permission denied]

On the other hand, it is advisable to get used to using double quotes when dealing with the arguments that you receive. This way you will avoid future problems by saying things like:

$ v="hola que tal"
$ if [ -z $v ]; then echo "vacio"; fi
bash: [: too many arguments
$ if [ -z "$v" ]; then echo "vacio"; fi

That is, in the first case, everything is expanded to something that is too many arguments for the operator test :

if [ -z hola que tal ]
answered by 25.07.2017 / 15:05

In shell scripting, the expressions that go into a condition can go in several different ways:

  • Preceded by operator test . It is equivalent to the following.
  • Wrapped in simple brackets [ . It is the traditional boolean check and is available in all POSIX shell.
  • Wrapped in double brackets [[ . It is an extended version of the previous ones that works in bash, it allows to execute more advanced verifications, like for example regular expressions.
  • Wrapped in simple parentheses ( . Execute the expression in a subshell.
  • Enveloped in double parentheses (( . It is used for arithmetic expressions.
  • Without anything . Simply execute the command that goes next and the if will be made depending on the result of the command.
  • In your particular case:

    • When you have the test in the comparison, the expression is processed as a logical expression and will be entered in if if parameter 1 is less than or equal to parameter 2.
    • When you remove the test , what you do is that you try to execute the expression: you look for the executable that matches with parameter 1, and you pass the modifiers -lt and parameter 2 as parameter. Since parameter 1 does not match any file or program present in the directory, the error is shown that the file to be executed has not been found.


    answered by 25.07.2017 в 15:11