Admittedly, Python's argparse is a versatile and powerful beast. But even after rereading the official docs, as well as many Q&As about argparse across the SE sites, I'm still unsure if this isn't possible or if I just lack the finer points og argparse.
For a tool tool with many subcommands (such as abc and def) I would like to implement subcommand-related help, preferably in the form of tool abc help, tool def help, and so on. However, these subcommands usually have positional arguments, such as tool abc FOO and tool def FOO BAR, with FOO and BAR being metavariables for which the CLI user needs to supply concrete values. abc and def are verbatim commands or "optional positional arguments" (if they may be called such at all).
Is there something like an optional command? Is this possible at all?
Related
I see this both in man page and in emacs lisp doc string, it looks like a convention; is there a formal document about that?
what contexts should I follow this rule?
#lawlist has answered wrt where you can find the doc about this.
The reason for this convention is that it allows the code that composes a help buffer to recognize things for what they are: variables, functions, macros, keys, etc., and put links on them to take you to other help buffers. Without the convention it is much more problematic trying to determine whether foo refers to variable foo, function foo etc.
I like to call truncate(const char *path, off_t length) (see man 2 truncate) directly from the command line or in shell script.
I guess I could embed a C program and then compile, run, and remove it.
Another short alternative is using perl -e "truncate($file,$length)".
Questions:
Is perl -e "syscall(params...)" the most common pattern to invoke syscalls? How well does it cover other syscalls?
Is there another common way to invoke Linux/BSD syscalls from the shell?
For instance, using a command like syscall "truncate($file,$length)"?
Thank you for all comments and suggestions. I conclude the following answers to my questions:
Some scripting languages, e.g., perl, may provide functions that resemble or wrap some of the useful syscalls, i.e., those that would make sense calling from the shell.
However, there is no 1:1 mapping of scripting APIs and syscalls and no "common pattern" or tool to invoke many different types of syscalls from the shell.
Moreover, a generic solution for a specific problem should not focus on syscalls in the first place, but rather use a generic language or library from the beginning. For instance, for file truncation this may actually be perl, using perl -e "truncate($file,$length)".
http://julia.readthedocs.org/en/latest/manual/metaprogramming/ discusses macros in Julia, which usually start with #, but also lists two special macros, text_str, and cmd, which handle text"string" and `shell command`, respectively. Is there a comprehensive list of these special macros supported by Julia? Is it possible to define your own?
So all the macros, including string literal macros, are in exports.jl.
If you are asking about these special syntax transformations in general like string literal macros, I don't think thats a question thats easily answerable: there are multiple arbitrary syntax translations like that that you can't do in user code (without using an # to denote you are transforming syntax with a macro). Most Julia macro-or-function-looking things aren't magic, but string literals, ccall, and maybe even things like A'c and the like would qualify.
The most sure-to-be-up-to-date way to find out is to enter the folder base and say grep # exports.jl. If you're not on a Unix-like platform, then opening that file and looking at the # Macros section will also work.
It is indeed possible to make your own; in fact every macro of the form
macro x_str(...)
end
is a String macro. Since 0.6, command macros are also supported by
macro x_cmd(...)
end
This is naive question for which I struggled to find an elegant solution. I write perl scripts that as they mature, grow in the number of options passed to GetOptions. The important options for the script, I add on top as POD documentation, but I rely on giving meaningful names to the other options, and I don't bother to document them explicitly.
I would like to pass the hash in GetOptions somehow to the content printed by perldoc, so that the non-documented options is listed there. Any option?
perldoc parses pod. You'd have to write a script to modify your .pl's pod based on values obtained by running your .pl... Yeah, that doesn't sound like a good idea.
You might be interested in Getopt::Euclid, Docopt, Getopt::Auto or Getopt::AsDocumented. These take the opposite approach: You define the options in the documentation, and they parse the documentation to determine how to process the command line.
I ralize that your point of view is code first and document later the things that become stable. That is fair when you need to write twice docs and code. But nowadays that is not true. My recomendation for prototyping is write the manpage and use a module that create the code of the options for you.
My favorite in perl and python is docopt (and has implementations for many other languages). Here you can find the Perl Docopt
I asked about perl implementatios for docopt long time ago in stackoverflow and I was pointed to the docopt module and other options like Getopt::Euclid, Getopt::Auto and Getopt::AsDocumented
Related with your concern about not incrementing cpan dependencies,
in python Docopt is selfcontained but I think it is not true for perl implementation which depends on
boolean,
Class::Accessor::Lite,
List::MoreUtils,
List::Util,
parent,
Pod::Usage
and
Scalar::Util; and the dependencies of the dependencies....
If the perl Docopt implementation is not as small and selfcontained as the original Python then probably is time to give it wider usage and start to fill feature/implementation requests because, IMHO, the doctopt way of doing things is ONE of the many ways of doing the things right.
Finally here you have a talk about the why of docopt. It is about python but command line interfaces logic and UX are the same for all the languages: PyCon UK 2012: Create beautiful command-line interfaces with Python
I have a custom script that takes hostnames as parameters. I know that I can easily copy the existing completion of ssh like this:
compdef myscript=ssh
But that only enables completion of the 1st parameter. Is there an easy way to enable the same completion for all parameters?
I'm not aware of an easy method to enable completion for a custom command. Assuming you've got a command foo with a bunch of allowable arguments bar, bas or baz, then the completion is easy: you can either have foo bar, foo bas, or foo baz. If they're not or'd, though, you could have any combination of the three.
It gets somewhat worse when you've got a 'depth' of more than 1 (bar can take arguments car, cas and caz, for example).
In zsh, my general understanding is that completion for commands is detailed in completion functions. These functions are application specific, because the arguments for each application are specific to those applications. As an example, the tmux (a terminal multiplexer, similar to screen, in case you're not familiar) has a completion function that's fairly complex: here's a link.
If you want to write your own completion functions, the documentation is available and accessible. Here are a bunch of links that I'm (slowly) working my way through - they'll definitely tell you how to get completion working, but there's a lot of reading. The Z-Shell is a complex beast.
Z-Shell completion introduction
Z-Shell functions: Writing and loading your own
ZSH Users Guide, Ch. 6: "Completion, old and new"
You're specifically interested in enabling completion for hostname-like arguments, and you've singled out ssh as the idea. The zsh completion function for ssh is defined in Completion/Unix/Command/_ssh, if you've got the ZSH source. If not, here's a link.
Of course, this SO question is rather similar. compdef alone may do what you want, if myscript and ssh parameters are identical enough.