Designing command-line interfaces
antoarts.com
Designing command-line interfaces
1–10 of 81 posts
Re: Designing command-line interfaces
#2I'm also working on a project where by entering "?" at any interactive section you're taken to an interactive help menu. From here you can query (amongst other things) the state of the program, something that isn't always clear when you're using command line software, as you can't have extra info somewhere in the corner or whatever.
Re: Designing command-line interfaces
#3Provide explicit flags for default behavior.
For example, if your lines-of-code counting utility excludes preprocessor directives by default, and includes them when you pass "-i", provide an "-x" switch that signals to use the default behavior. This way, when someone wants to write a bash script that uses your utility, they can do this:
case $include_directives in
y)
LOC_FLAGS='-i';;
n)
LOC_FLAGS='-x';;
esac
myloc $LOC_FLAGS
This has three benefits:1.) It's explicit, and thus more obvious and clearer.
2.) It's more consistent, so there's no risk of empty/unset variables, whitespace, or other edge conditions screwing up a delicate munging operation.
3.) It's change-tolerant, so if future versions of your utility change the default behavior, scripts will continue functioning as expected.
Re: Designing command-line interfaces
#4That's disappointing, I was hoping I'd learn how vi, etc. worked from this, since I know nothing about writing command line interfaces other than input and output to the last column of the last line of the terminal. Does anyone know of a good article/introduction to this?
Re: Designing command-line interfaces
#5---
Speaking from an experience writing CLIs for configuration-heavy embedded devices, the key design element of a functional CLI is a context-aware TAB expansion. This is what makes a CLI truly convenient for routine use.
For example, if a mysql shell was smarter, it would've been allowing this:
> use p expands to "use production"
> show c s expands to "show columns from secondary"
> select * f s ... expands to "select * from secondary ..."
It would also be nice to make OS shell more aware of individual commands' options, and to allow for example: # ip addr shows "ip addr add"
# shows "ip addr del"
# shows "ip addr"
This is possible through hardcoding these expansions into the shell, but that's not very elegant, is it? On the other hand allowing to integrate arbitrary commands with the shell in a generic way would require putting together some sort of interface/manifest contraption and it would most likely go against the very spirit of Unix simplicity. So catch 22 it is.Re: Designing command-line interfaces
#6Non-interactive programs get the most attention in this article, while text-based user interfaces are barely covered at all. That's disappointing, I was hoping I'd learn how vi, etc. worked from this, since I know nothing about writing command line interfaces other than input and output to the last column of the last line of the terminal. Does anyone know of a good article/introduction to this?
Re: Designing command-line interfaces
#7Use your language's command-line option processing libraries.
OptionParser in ruby and argparse in python. There is no reason to eschew these libraries: they're part of the standard library, they require zero coupling to your app logic, and they handle all of the edge cases for free.
"But I can just shift the arguments", you say! Yeah? Great! What if the user pipes input through STDOUT? What if the user passes a flag, a required argument, and then another flag? Will your script read the last flag correctly, or has the naive logic already entered "required argument processing mode"? Just use the library. It's a solved problem!
Re: Designing command-line interfaces
#8(edit) There is a bit of terminology substitution going on in linked article. Command line interface is a shell. That's where one types the commands. Calling command options and arguments an interface may be technically correct, but it is not what is conventionally understood under a term of CLI . --- Speaking from an experience writing CLIs for configuration-heavy embedded devices, the key design element of a functi…
Re: Designing command-line interfaces
#9(edit) There is a bit of terminology substitution going on in linked article. Command line interface is a shell. That's where one types the commands. Calling command options and arguments an interface may be technically correct, but it is not what is conventionally understood under a term of CLI . --- Speaking from an experience writing CLIs for configuration-heavy embedded devices, the key design element of a functi…
Context-aware tab completion is very doable in the unix world, actually; it's just a hassle on the part of the utility-writer. Have you ever noticed that if you add a new file "foo/bar/baz.py" to a mercurial repository and type "hg add fo", it will autocomplete all the way to "foo/bar/baz.py", without stopping at each directory? This is because hg has overridden the default tab completion provided by bash and defined its own set of possibilities.
I wish it were easier to set up; I think if that were the case, we'd see a lot more utilities with spot-on tab completion.
Re: Designing command-line interfaces
#10Oh, and another: Use your language's command-line option processing libraries. OptionParser in ruby and argparse in python. There is no reason to eschew these libraries: they're part of the standard library, they require zero coupling to your app logic, and they handle all of the edge cases for free. "But I can just shift the arguments", you say! Yeah? Great! What if the user pipes input through STDOUT? What if the u…