Aquí hay dos cuestiones relacionadas.
Primero, la pregunta del OP, ¿Por qué 0 es verdadero pero falso es 1 en el caparazón? y el segundo, ¿por qué las aplicaciones devuelven 0 para el éxito y no cero para el fracaso?
Para responder a la pregunta del OP, debemos comprender la segunda pregunta. Las numerosas respuestas a esta publicación han descrito que se trata de una convención y han enumerado algunas de las sutilezas que ofrece esta convención. Algunas de estas sutilezas se resumen a continuación.
¿Por qué las aplicaciones devuelven 0 para el éxito y no cero para el fracaso?
El código que invoca una operación necesita saber dos cosas sobre el estado de salida de la operación. ¿Salió la operación con éxito? [* 1] Y si la operación no se cierra correctamente, ¿por qué la operación se cierra sin éxito? Se puede utilizar cualquier valor para indicar éxito. Pero 0 es más conveniente que cualquier otro número porque es portátil entre plataformas. Resumiendo la respuesta de xibo a esta pregunta el 16 de agosto de 2011:
Zero es independiente de la codificación.
Si quisiéramos almacenar uno (1) en una palabra entera de 32 bits, la primera pregunta sería "¿palabra big-endian o palabra little-endian?", Seguida de "¿cuánto tiempo componen los bytes una palabra little-endian?" ", mientras que cero siempre se verá igual.
También es de esperar que algunas personas lancen errno a char o short en algún momento, o incluso a flotar. (int) ((char) ENOLCK) no es ENOLCK cuando char no tiene al menos 8 bits de longitud (las máquinas de caracteres ASCII de 7 bits son compatibles con UNIX), mientras que (int) ((char) 0) es 0 independiente del detalles arquitectonicos de char.
Una vez que se determina que 0 será el valor de retorno para el éxito, entonces tiene sentido usar cualquier valor distinto de cero para el fracaso. Esto permite que muchos códigos de salida respondan a la pregunta de por qué falló la operación.
¿Por qué 0 es verdadero pero falso es 1 en el shell?
Uno de los usos fundamentales de los shells es automatizar procesos mediante secuencias de comandos. Por lo general, esto significa invocar una operación y luego hacer otra cosa de manera condicional en función del estado de salida de la operación. Philippe A. explicó muy bien en su respuesta a esta publicación que
En bash y en shells de Unix en general, los valores de retorno no son booleanos. Son códigos de salida enteros.
Entonces es necesario interpretar el estado de salida de estas operaciones como un valor booleano. Tiene sentido asignar un 0
estado de salida exitoso ( ) a verdadero y cualquier estado de salida distinto de cero / error a falso. Hacer esto permite la ejecución condicional de comandos de shell encadenados.
He aquí un ejemplo mkdir deleteme && cd $_ && pwd
. Debido a que el shell interpreta 0 como verdadero, este comando funciona convenientemente como se esperaba. Si el shell interpretara 0 como falso, entonces tendría que invertir el estado de salida interpretado para cada operación.
En resumen, no tendría sentido que el shell interpretara 0 como falso dada la convención de que las aplicaciones devuelven 0 para un estado de salida exitoso.
[* 1]: Sí, muchas veces las operaciones necesitan devolver más que un simple mensaje de éxito, pero eso está más allá del alcance de este hilo.
Consulte también el Apéndice E en la Guía avanzada de secuencias de comandos Bash