I am writing a CLI application that produces a binary non-executable artifact. It does not conform to any specific format, and I think convention would be to create a .bin file.
I think I also want my CLI application to be able to send it to stdOut (so users can pipe it) and send it to ZON (when that is merged) (as a file or to standard out).
How would you expect the CLI application to be structured? Like this?
Output to .zon file
gatorcat read-eeprom --format zon -o foo.zon
Output to .bin file
gatorcat read-eeprom --format zon -o foo.zon
Output to stdOut as binary? Is it ok to output nulls to stdOut?
My personal preference for textual output is simply to default to stdout, and let users use shell redirection to write it to a file, I actually don’t even care if there is dedicated --output argument in such cases.
For binary data, its output is meaningless when displayed in a terminal, as well as possibly quite large, I would definitely opt to make outputting to stdout an explicit action in this case, and not do so automatically just because a user didn’t specify an output file. As @gonzo pointed out, the common convention here is to use -.
In think in cases like this it’s best to look at existing tools, preferably from similar domain, and try to adhere to the conventions they’re using.
Related, although it doesn’t directly answer your question, but might be worth reading: http://www.catb.org/~esr/writings/taoup/html/ch10s05.html
In case it is relevant: I had issues with writing binary data to stdout on windows. I cannot remember the details any more, but I think the windows console api expects some text encoding. At the time I wanted to write a signal processing pipeline. After switching to windows it took me a while to realize that this was the issue.
One way to mitigate this issue is to check whether the stdout file is a TTY (terminal) by calling std.fs.File.isTty on it. That way, the program can avoid dumping binary data directly to the user’s terminal (unless specifically requested to) while still working as-is using a pipe or output to a file. Several common programs do things like this, such as ls formatting output more compactly when printing to a terminal (compare ls and ls | cat) and gzip (at least the GNU version) which applies the same sort of safety check:
$ echo hi | gzip
gzip: compressed data not written to a terminal. Use -f to force compression.
For help, type: gzip -h
$ echo hi | gzip >hi.gzip
# works