Improving CLIs with isatty
blog.jez.io
blog.jez.io
"...please don’t make the behavior of a command-line program depend on the type of output device it gets as standard output or standard input."
https://www.gnu.org/prep/standards/standards.html#User-Inter...
Of course you don't have to follow their standards, but their rationale for this particular item is reasonable.
I think a warning as described in the article is perhaps just about OK though.
And I go around piping things into 'less -RS'
I wouldn't get the warning.
Though of course getting it to some is probably better than none so I'm more than likely with you.
--
Unfortunately many apps do behave differently towards ttys in one key way - colour.
It is somewhat frustrating to be piping into less something like 'apt list --upgradable' and being unable go essuly scan because its a mess without colour.
To use an analogy from web browsers, the equivaleny guideline would be asking websites not to detect features by reading the User-Agent, and using feature detection instead.
if [ -t 0 ]; then
fi
I then use this flag to know if I should do things like export CLI progress bars or other interactive things.It only works when isatty() returns true on both stdin and stdout. If you redirect stdin from a file, but stdout still goes to tty, isatty() on stdout will return true, but System.console() will return null.
If you are using isatty() on stdout to decide whether to display fancy output, then whether stdin is a tty or not isn't relevant. So in that scenario System.console() doesn't do what you want.
For JNA (probably JNR too, my personal experience is only with JNA though), just have to add the JAR to your project (or the Maven/Gradle dependency). The JAR includes native libraries for various platforms.
It is non-portable, it won't work on Windows, although you may not care about that, and if you do, Windows has similar APIs (e.g. calling GetConsoleMode() on the file handle will fail if the handle doesn't point to a console.)
If you really wanted to add this 'protection code', you could make a bash wrapper around every Unix command that has its input or output connected to a tty. Not perfect, but it would eliminate a whole lot of extra tty-checking code from every app, providing a single reliable interface. I imagine you'd turn it off after a while, though.
It is not in the C standard library, it's in POSIX so isn't available in non-*nix platforms. The same problem applies in other languages using it through cffi.
[0]: https://git.musl-libc.org/cgit/musl/tree/src/unistd/isatty.c
(The POSIX standard does standardise ioctl, but only for use with STREAMS, which is an optional feature which more often than not isn't implemented.)
I meant there is no ioctl method in the Java standard library. So how do you call it without using some FFI to import the method? You cannot.
https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46#...