Why is it "while kill -0 $PID" and not "until kill -0 $PID"?

I may be being daft here, but if I want to do something while a process is running, why do I do:

while kill -0 $PID
do
    #...
done

instead of

until kill -0 $PID
do
    #...
done

?

kill -0 exits with code 1 if the process is not found, and 0 if the process is found:

$ kill -0 123444
-bash: kill: (123444) - No such process
$ echo $?
1
$ screen -ls | grep rofl
    28043.rofl  (02/19/2015 02:27:56 PM)    (Detached)
$ kill -0 28043
$ echo $?
0

So if the process is running, wouldn’t the while loop boil down to:

while 0
do
    #...
done

which would then never execute?

Asked By: Claudiu

||

The exit code is not a boolean value, is an integer, by convention the zero value is success, so you are thinking in negative logic from Bash’s point of view

Answered By: xae

The shell does not expanded condition like you think.

In shell, an error code 0 indicated that the command has completed successfully. Any non-zero error code indicated that there was error.

For more concisely, POSIX define while loop as:

The while loop shall continuously execute one compound-list as long as
another compound-list has a zero exit status.

The format of the while loop is as follows:

while compound-list-1
do
    compound-list-2
done

The compound-list-1 shall be executed, and if it has a non-zero exit
status, the while command shall complete. Otherwise, the
compound-list-2 shall be executed, and the process shall repeat.

Answered By: cuonglm

When dealing with return codes “0” is a success and non-zero is failure. The syntax of a while loop is:

while COMMANDS; do ...; done

The while statement checks the return code of the last command in the provided list of commands. In you last example of while 0, this will attempt to execute a command called “0” and check it’s return code.

A literal 0 is not special to bash outside of arithmetic context. Inside of that context, 0 is considered false. For example

while (( 0 )); do
  ... # never executes
end

This case is special as the keyword (( is treated as a command, which returns non-zero because it’s result is 0.

Answered By: jordanm

The “while” command isn’t looking for a boolean value, it’s looking for a return code of “0” which indicates successful execution of the command. So in the case the while command, a command that returns 0 is “true” and anything else is “false”.

Even when you’re doing a comparison, Bash treats that like a command which is returning a successful error code (0) when the comparison is true.

Answered By: Degenerate DevOps