Documenting bash functions - bash

I would like to add documentation for bash functions so that users can lookup the functions with man. There should be no visible difference between my functions and actual commands.
I know I can do this by overriding man with a function that checks for my own functions. Is there another way?

If you have your man pages created (which is a task in itself) then what you can do is put them somewhere on the system like /usr/local/man (or wherever you like, really), then edit the system-wide $MANPATH variable to include that location. Then the man pages will be available.

Real shell functions are not documented by individual man pages but by the help builtin command. You would have to override that. But even I would not look there for information.
Just generate normal man pages and throw them into /usr/local/man/manX or /usr/local/share/man/manX - whatever your distribution already provides. Check /etc/manpath.config that this directory is already mentioned there. That way no one must fiddle in their startup files with the MANPATH environment variable.
Each manpage should also contain a clearly visible section explaining, that this is a function and not a command and what the difference is.
After that the social part kicks in: Tell everyone at every occasion about that documetation. By every I mean every, not only suitable. :-)

Related

What is `ac_cv_func_malloc_0_nonnull` as provided to ./configure?

I'm cross-compling with mingw and got this error:
undefined reference to `rpl_realloc'
After some searching I found this can be resolved as follows in configure.ac or as environment variables set prior to calling ./mingw64-configure:
ac_cv_func_malloc_0_nonnull=yes
ac_cv_func_realloc_0_nonnull=yes
What defines these macros, and as there any documentation on the subject? I couldn't find any...
What defines these macros, and as there any documentation on the subject?
Autoconf uses the ac_cv_ prefix for its "cache variables", in which it records the results of configuration tests it has performed. In the event that the same check is requested multiple times, these allow it to use the previously-determined result instead of performing the check again.
The general naming convention for these is documented in the Autoconf manual. The particular cache variable names you ask about are documented to cache the results of the Autoconf's AC_FUNC_MALLOC and AC_FUNC_REALLOC macros, respectively. That documentation also speaks to the rpl_realloc name.
It is allowed to use these variables in configure.ac to programmatically determine the results of those checks, but it is a relatively nasty hack to assign values to those variables directly. In this particular case, however, the error suggests that whoever prepared the autotooling for the project you're trying to build did a sloppy job of it. If fudging the cache variables gets you a successful build and a working program then that's a tempting and much easier alternative to actually fixing the project.

Check for wildcard in fish shell arguments

In writing a function for fish shell I want to know if a lone wildcard (not part of a bigger expression) was used in the command arguments. Fish does the wildcard expansion before passing arguments to my function, so there is no easy way that I can see to do that, aside from check whether the arguments are the same as the output of ls. The inefficiency of that method makes me sad, though. Is there a better way to do this, without going into fish's source code?
EDIT:
Thanks for the input. Specifically, I am looking to add some functionality like zshell has for warning if there is a * in the arguments of rm. I know that there was an issue opened on GitHub specifically about this but I couldn't find the link again. I have typod, for example, rm * .o instead of rm *.o, and accidentally deleted all my code (... which I brought back from git, but still).
EDIT 2:
Here is the issue on GitHub: https://github.com/fish-shell/fish-shell/issues/1511
No, there's no way for a function to tell where its arguments came from. Maybe if you give more details about what you're really trying to accomplish, we can give another suggestion.

Determine if bash/zsh/etc. is running under Midnight Commander

Simple question. I'd like to know how to tell whether the current shell is running as a mc subshell or not. If it is, I'd like to enter a degraded mode without some features mc can't handle.
In particular, I'd like this to
Be as portable as possible
Not rely on anything outside the shell and basic universal external commands.
Though it's not documented in the man page, a quick experiment shows that mc sets two environment variables: $MC_TMPDIR and $MC_SID. (It also sets $HISTCONTROL, but that's not specific to mc; it affects the behavior of bash, and could have been set by something other than mc.)
If you don't want to depend on undocumented features, you can always set an environment variable yourself. For example, in bash:
mc() { MC_IS_RUNNING=1 command mc "$#" ; }
Entering a "degraded mode" is another matter; I'm not sure how you'd do that. I don't know of any way in bash to disable specified features. You could disable selected built-in commands by defining functions that override them. What features do you have in mind?

Does Cygwin (or an actual UNIX shell) have some command to import names from another namespace to the current namespace, as in Python?

In Python, we can use "import" to import the names of another namespace into the current namespace.
Similarly, is there a notion like "namespace" in existence in UNIX shell scripting at all? If so, then does Cygwin (or an actual UNIX shell) have some command to import names from another namespace to the current namespace, as in Python? Thanks.
Note to the community members with admin priviledges: I really think this question IS a programming question instead of a "superuser" question. Please kindly elaborate on why if you disagree with that. Thanks a lot for your time.
There is no way to do exactly what you are asking for.
The source envFile command and it's alternate . envFile can be very helpful.
envFile file will just be a list of environment assingments.
FrontOfficeSystem=MyFrontOffice
BackOfficeSystem=myBackOffice
When you include the command in your script to 'source' the envFile (any name will work), the shell reads the code as if it was directly in your main shell script. Like 'include' in a lot of langauges. But namespaces, ... nope. See next.
More helpful : see indirect references in advanced Bash scripting, this is probably better than using eval ... (per below), but I haven't had the opportunity to work with it.
finally, you may also benefit from eval and varname indirection, i.e.
src=FrontOffice
eval \$${src}System="${src} has data"
src=BackOffice
eval \$${src}System="${src} has data"
Not a great example, but I don't have access to the scripts where I really went to town on this idea. It helped me genericize (sp) some code that otherwise would have had to be repeated 10 times, for each data src (I put the repeating block of code in a for loop, with the src names as the element list for the for(each), then the eval would expand ${src}System as FrontOfficeSystem, BackOfficeSystem). If you windup with spaces in your values for your src list, then all bets are off.
use set -vx in your terminal window and copy/paste above code to see how it works. It might help.
I hope this helps.
P.S. as you appear to be a new user, if you get an answer that helps you please remember to mark it as accepted, and/or give it a + (or -) as a useful answer.

How does bash tab completion work?

I have been spending a lot of time in the shell lately and I'm wondering how the tab autocomplete works. What's the mechanism behind it? How does the bash know the contents of every directory?
There are two parts to the autocompletion:
The readline library, as already mentioned by fixje, manages the command line editing, and calls back to bash when tab is pressed, to enable completion. Bash then gives (see next point) a list of possible completions, and readline inserts as much characters as are identified unambiguously by the characters already typed in. (You can configure the readline library quite much, see the section Command line editing of the Bash manual for details.)
Bash itself has the built-in complete to define a completion mechanism for individual commands. If for the current command nothing is defined, it used completion by file name (using opendir/readdir, as Ignacio said).
The part to define your own completions is described in the section Programmable Completion. In short, with
complete «options» «command» you define the completion for some command. For example complete -u su says
when completing an argument for the su command, search for users of the current system.
If this is more complicated than the
normal options can cover (e.g. different completions depending on argument index, or depending on previous arguments),
you can use -F function, which will then invoke a shell function to generate the list of possible completions.
(This is used for example for the git completion, which is very complicated, depending on subcommand and sometimes
on options given, and using sometimes names of branches (which are nothing bash knows about).
You can list the existing completions defined in your current bash environment using simply complete, to have an impression on what is possible. If you have the bash-completion package installed (or however it is named on your system), completions for a lot of commands are installed, and as Wrikken said, /etc/bash_completion contains a bash script which is then often executed at shell startup to configure this. Additional custom completion scripts may be placed in /etc/bash_completion.d; those are all sourced from /etc/bash_completion.
If you are interested in the basics:
Bash uses readline which features history and basic completion. You could inspect the source if you want to get a detailed understanding.
Furthermore, you can use readline to build your own CLI interfaces with completion

Resources