Issue
In C and many other languages, 0 means false and 1 ( or non-zero ) means true. In the shell 0 for the status of a process means success and non-zero means an error. Shell if statements essentially use 0 for true. Why did the writer of the first shell decide to use 0 for true?
Solution
The OP asking about the
Why did the writer of the first shell decide to use 0 for true?
The short answer: Isn't possible to answer this question in this form, because the first shell has not any exit status.
EDIT
Because @John Kugelman asked for summarisation, this answer getting a bit long.
Nor the second, third and Nth shell hasn't anything that could be called "the exit status". For the approximative correct answer, need to go to deeper into the history.
The shell was invented by "Louis Pouzin" as the "RUNCOM" tool, in the MIT's Compatible Time-Sharing System read about CTSS, where is written:
Louis Pouzin also invented RUNCOM for CTSS. This facility, the direct ancestor of the Unix shell script, allowed users to create a file-system file of commands to be executed, with parameter substitution. Louis also produced a design for the Multics shell, ancestor of the Unix shell.
Read also this page.
The "next level" was in the Multics, called as the Multics Command Language:
The command language interpreter, the Shell, is normally driven by the Listener.
Its function is to listen for requests in the form of command lines typed in at the user console. In the above command language description, the listener reads in a line from the console, evaluates the line as a command, and re-calls itself to repeat the function.
It hasn't anything that could be called "exit status".
The programs calls the terminate{file/process} procedure
,
what stops the program execution.
And this is one of the most important points. Need differentiate between
- the exit as system call
When you terminating a running (compiled) program, (for example, in "C" using the
exit(N)
) in the reality you call a library function, what makes the bridge to the underlying operating system and correctly terminates the program. This means the "exit(N)" (from the point of view of the exit function) is OS implementation-dependent. See Wikipedia - shell's exit status -
The exit status of an executed command is the value returned by the
waitpid
system call or equivalent function. Wikipedia. The waitpid like functions usually returns the exit status from the previous point, but it is OS implementation-dependent. (ofc, now standardized by POSIX).
Back to the history:
After the Multics, the UNIX got developed. From this page
the shell
as we know today has two predecessors:
- the Thompson shell (version 1 up to version 6) - if someone is interested, here is maintained a runnable version for the v6.
- and the Programmers Work Bench [PWB] shell
- the first shell that we known today was the Bourne shell V7
If interested, read through the manuals - links are here.
The first mentioning of the "exit code" is in the Manual of the PWB (aka Mashey) Shell. All shells "before" talks only about the:
Termination Reporting
If a command (not followed by "&") terminates abnormally, a message is printed. (All terminations other than exit and interrupt are considered abnormal.)
So, the answer to the question is in the above lines, - in line what is already said in the comments:
- Because read the exit code as an error code. 0-mean no error. >0 some error.
- Probably because there's only one mode of success and many modes of failure.
Nice citation from the PWB shell manual
$r is the exit status code of the preceding command. ``0'' is the normal return from most commands.
Notice the: most word. :), e.g. it was not invented in "one moment" by someone, but it is evolved in time. And it very tightly depends on the implementation of the exit
and wait-like
calls in the underlaying OS.
For example, the 1st version of UNIX know nothing about the exit(N)
levels - it was a simple exit()
and the wait
didn't return a specific value - from the The first edition of the Unix Programmer's Manual, dated November 3, 1971
exit is the normal means of terminating a process. All files are closed and the parent process is notified if it is executing a wait.
wait causes its caller to delay until one of its child processes terminates. If any child has already died, return is immediate; if there are no children, return is immediate with the error bit set.
Also, read here - really worth - The Evolution of the Unix Time-sharing System - about the evolution of the fork
, exec
, exit
and wait
...
The V7 standardized the exit status as:
The value of a simple command is its exit status if it terminates normally or 200+status if it terminates abnormally (see signal(2) for a list of status values).
also:
DIAGNOSTICS Errors detected by the shell, such as syntax errors cause the shell to return a non-zero exit status. If the shell is being used non interactively then execution of the shell file is abandoned. Otherwise, the shell returns the exit status of the last command executed (see also exit).
Howg.. OMG... Someone could be so nice as to edit this post and correct my broken English and/or extend/correct the above...
And finally - sorry folks - totally of the topic - but can't resist adding the following image from the history - not many current users know Microsoft-XENIX. ;)
Answered By - jm666