user6186249
user6186249

Reputation:

KSH: IF condition issue: if test .... then vs if ... then

what is the difference if I put test or without test in a .ksh file?

if test $1 -ne 0 ; then ....

and

if $1 -ne 0 ; then ....

Many Thanks

Upvotes: 0

Views: 1870

Answers (1)

Henk Langeveld
Henk Langeveld

Reputation: 8446

I actually think this is an important question, as it highlights some important rules in shell programming:

  1. Every command in the shell returns an true (0) or false exit code
  2. Control structures in the shell do not require comparisons

Every command in the shell returns an exit code

Any properly coded command in the shell will return 0 for success, and non-zero for failure. While there is only one way to succeed, but always more than way to fail.

Example:

$ no-such-command || echo no $?
ksh[1]: no-such-command: not found [No such file or directory]
no 127
$ 

The exit status of a command is caught in the pseudo variable $? and is available until you complete another command.

This exit status is used in control structures like if ... then ... fi or until ... do ... done.

failing(){ return 2; }
failing &&
    echo "It works" ||
    echo "It failed with exit code $?"

results in

It failed with exit code 2

Control structures in the shell do not require comparisons

Let's start with the simplest definition of the if command:

if compound-list
then
    compound-list
fi

For the full syntax, see Section 2.9.4 Compound Commands of Shell Command Language of The Open Group Base Specifications.

Between the keywords, if, then, and fi there are two sections of code, named compound-list.

This is shorthand for any sequence of code that would be valid in a script. The exit status of the list will be equal to the exit status of the last command in the list.

The important difference for the two lists is that the firts will determine the flow of control, while the second determines the exit status of the entire expression, when executed.

Conclusion

Any command can be used as the test in an if/then/else/fi construct. Because we often want to test things explicitly, we often use the actual test command or its derivatives [ ... ] and [[ ... ]].

if [[ -n $1 ]]; then
    echo "'$1' is a non-empty string"
fi

For complex expressions it is always preferred to wrap them in a function to apply some abstraction.

One more trivial example:

non_empty_files_present(){
  (path=${1:?directory expected}
    (find ${path} -type f -size +0 | read line) 2> /dev/null
  )
}

if non_empty_files_present /var/tmp; then
  echo "Some files have content"
fi

Upvotes: 1

Related Questions