Git-style subcommands done right
APACHE-2.0 License
With commands it's trivial to create a git-inspired program that use specialized subcommand binaries to perform specific tasks.
Just compile the command.c into your custom command name, and it just works. Subcommands have to comply with some conventions so that all fits, but all conventions are very easy to comply with, even on bash scripts.
Commands is intended to be used by just compiling and changing the binary name for very simple commands, or to be extended as necesary for more complex ones.
I'm well aware of hemsman (https://github.com/mattmcmanus/node-helmsman) and git-style-binaries (https://github.com/jashmenn/git-style-binaries) but both are everything but unobtrusive by the minimal reason that they need a specific interpreter (node, ruby). Maybe there are other solutions that use python or similar, but with commands, its just one C file and conventions.
Compile, change the executable name to your command name.
They must accept just one command line argument: --one-line-help. It must return a one line help line, to be print when commands is run without arguments.
The subcommands must be in any PATH directory with name [mycommand]-[subcommand]. They are looked for in order.
Your commands do not need to be exactly at a $PATH file; there is a config file at /etc/[yourcommand], or ~/.config/[yourcommand]. All lines will be read and set as environment variables. There is a COMMANDS_PATH envvar, which by default is set to $PATH, but can be set to any other place.
The config files can contain envvar variables as in bash: $VAR and ${VAR}.
List of users using bash acording to getent passwd:
#!/bin/bash
if [ "$1" == "--one-line-help" ]; then
echo "List all users"
exit 1
fi
getent passwd | awk -F: '{ if ($7 == "/bin/bash") print $1; }'
If these definitions are present, they may set default values:
Using the preinit_f, its possible to add your own internal commands, which can be simple functions, or full commands with its own args.
Check how it done at subcommand_list_init. You must do something similar on your preinit_f, which will be called in this very same function.
Internally the following environment vars are set before calling your comamnd.
It's possible to compile a limited shell of commands, using commands-shell.c
. It will allow only use
of this program commands (so security is actually on the commands side), and it also features a black
and white list.
Add the following variables to your config file:
SHELL_WHITELIST=...
SHELL_BLACKLIST=...
Both are optional, and both are used if avaliable, if a command is in both list it will not be allowed.
Careful that arguments (--help) are also commands, although normally internal.
You can use biicode to use commands in your project. It is the davidmoreno/commands block.