Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
TTY-Exit: terminal exit codes for humans and machines (github.com/piotrmurach)
61 points by pmurach on Feb 1, 2020 | hide | past | favorite | 14 comments


I'm not totally sure what the point of this is. This is advertised as exit codes "for humans and machines", however

* humans will always get way more information from a readable error message printed to stderr before exiting

* machines do not care about error details from third-party tools, apart from whether they are an input error (which can be blamed on the user, if they provided said input) or an internal error (including usage error) which is a bug and should be fixed by the calling program's developer

Indeed, the README has a lot of examples of using it in your child program, to report error, but no example of a parent program dealing with the reported error.


When I write a program that consumes output from other programs, I’ve never complained about them having meaningful exit codes rather than just returning 1 on every error. And I can use libraries like this for the consumption side, not just for production of errors.


This library improves the situation as:

* It includes default user-friendly error messages for all the built-in exit codes. For example, the code 64 will print " "ERROR(64): Command line usage error" to stderr.

* Machines, e.i. programs that, for example, watch over an executable can decided based on the error code what to do. If the program is interrupted by Ctrl-C then the parent program can handle the situation gracefully.

I totally agree that an example of using an exit code in a parent program would be beneficial.


It seems to be a Ruby equivalent to sysexits.h.[1] I don't know how widely used the codes are, but the idea is neat.

[1] https://manpage.me/index.cgi?apropos=0&q=sysexits&sektion=0&...


When I'm trying out a new language and writing programs in it that I'm going to invoke from the command line, one of the first things I do is put in those BSD-style extended error exit statuses. I also check along the way whether whatever option parsing library I'm using integrates at least EX_USAGE by default; the answer tends to be no, though I'm not sure how much of that is the library authors not knowing or intrinsically not considering them appropriate, and how much might be “new users will see this behavior, decide it looks complicated or bizarre, and leave”.


You're right. However, I'm also extending the set of exit codes with Bash recognised statuses[1]. This also includes a list of fatal signals, e.i. exit codes 128 + n, where n is a corresponding signal error.[2]

[1] http://tldp.org/LDP/abs/html/exitcodes.html [2] https://man.openbsd.org/signal.3


Meanwhile on OpenBSD[1]...

"A few programs exit with the following non-portable error codes. Do not use them."

[1] https://man.openbsd.org/sysexits


In this context "Do not use them.", these are reserved codes and shouldn't be redefined in your programs to mean something entirely different. So codes in range 64-78 are a standard across Unix systems. Usually, specific program codes are best served using codes below 64.

I have included a method that helps you check if a code is reserved or not. For example, TTY::Exit.exit_reserved?(126) will return true as this is a status used by Bash to indicate a problem with executing a command.


What does this have to do with ttys or terminals though?


Exit codes are only used in the context of terminal shells. So it seems appropriate to refer to terminals. Wouldn't you agree?


That's not the case at all. Every process produces an exit status when it terminates and many things besides interactive shells use them. Pretty much anything that runs a subprocess should retrieve the exit status to see if the child process was successful and log the failure if nothing else.

Some random examples: Automated build systems like Jenkins typically use the exit status to decide if a build task has succeeded. `make` also uses exit codes to decide if a child task has succeeded and may abort the rest of the build based on that and return an exit code itself. A local mail delivery agent like maildrop may return different exit status depending on if it's a permanent or temporary failure and the mail transfer agent decides if it should retry the local delivery based on that. The exit status of a Docker of Kubernetes container is usually based on a process exit status too.


Perhaps, but wait() and waitpid() do fill the status, and have no concept of a tty.


The TTY family of gems which this is a part of are focused on making development of CLI programs easier.


Why TTY in the name, exit codes are returned by processes, regardless if they opened a TTY or not.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: