Para uma primeira aproximação, 0 é sucesso, diferente de zero é falha, sendo 1 uma falha geral e qualquer coisa maior que uma sendo uma falha específica. Além das exceções triviais de false e test, que são projetadas para fornecer 1 para o sucesso, há outras exceções que encontrei.
Mais realisticamente, 0 significa sucesso ou talvez falha, 1 significa falha geral ou talvez sucesso, 2 significa falha geral se 1 e 0 forem usados para o sucesso, mas talvez também o sucesso.
O comando diff fornece 0 se os arquivos comparados forem idênticos, 1 se eles diferirem e 2 se os binários forem diferentes. 2 também significa falha. O comando less fornece 1 para falha, a menos que você não forneça um argumento; nesse caso, ele sai 0, apesar de falhar.
O comando more e o comando spell fornecem 1 para falha, a menos que a falha seja resultado de permissão negada, arquivo inexistente ou tentativa de ler um diretório. Em qualquer um desses casos, eles saem de 0 apesar de falharem.
Em seguida, o comando expr fornece 1 para sucesso, a menos que a saída seja a sequência vazia ou zero; nesse caso, 0 é sucesso. 2 e 3 são falhas.
Depois, há casos em que o sucesso ou o fracasso é ambíguo. Quando o grep falha em encontrar um padrão, sai 1, mas sai 2 por uma falha genuína (como permissão negada). O Klist também sai do 1 quando falha em encontrar um ticket, embora isso não seja mais uma falha do que quando o grep não encontra um padrão ou quando você está em um diretório vazio.
Portanto, infelizmente, os poderes do unix que parecem existir não impõem nenhum conjunto lógico de regras, mesmo em executáveis muito usados.