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
By
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
consequent-commands;
[elif more-test-commands; then
more-consequents;]
[else alternate-consequents;]
fi
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 ]