How to install custom man (manual) pages on mac os x - macos

I am trying to install a man page for a bash script on Mac OS X 10.9.5. The procedure that I tried to follow is summarised here: man page tutorial. I also summarise the steps that I tried below:
cp custom_command.1 /usr/local/man/man1/custom_command.1
gzip /usr/local/man/man1/custom_command.1
When trying man custom_command I receive the output No manual entry for custom_command. I also tried other installation methods mentioned in man page tutorial.
It is interesting to note that the steps above worked for the emacs console, i.e. I do get the correct manual when I type man custom_command. However, the command is not recognised by the autocomplete and I receive the following warning before I am able to read the manual: WARNING: terminal is not fully functional.
Any advice on how to resolve the issues above (i.e. both with the system terminal and the emacs console) would be appreciated.
Remark 1
For a reference, the man script that I am trying to install was taken from the tutorial and is restated below for a reference:
.\" Manpage for nuseradd.
.\" Contact vivek#nixcraft.net.in to correct errors or typos.
.TH man 8 "06 May 2010" "1.0" "nuseradd man page"
.SH NAME
nuseradd \- create a new LDAP user
.SH SYNOPSIS
nuseradd [USERNAME]
.SH DESCRIPTION
nuseradd is high level shell program for adding users to LDAP server. On Debian, administrators should usually use nuseradd.debian(8) instead.
.SH OPTIONS
The nuseradd does not take any options. However, you can supply username.
.SH SEE ALSO
useradd(8), passwd(5), nuseradd.debian(8)
.SH BUGS
No known bugs.
.SH AUTHOR
Vivek Gite (vivek#nixcraft.net.in)

First of all you may want to check if the man page your are trying to install is properly formatted and can be opened by man command. To do this pass the path to the man file to man command. It must contain a slash in order to be recognized as a path, for example:
man /usr/local/man/man1/custom_command.1
Then you should make sure the path you are installing your man page to is on the search list of man command. In order to find the man page its path must be either:
specified with -M option to the man command
set in the environmental variable MANPATH
listed in its config file (/private/etc/man.conf on OS X) under MANPATH statement or under MANPATH_MAP statement (which applies only to locations in your PATH environmental variable)
located in the location relative to where binary is installed, i.e.: if binary is installed in path/bin the man page is searched for in path/man, path/cat and path/bin/man, path/bin/cat
listed in files added in /private/etc/manpaths.d/ directory
The name of the man page file must be same as command name with optional section number. It may be gzipped.
To see where man will search for your custom_command man page run
man -d custom_command

OS X user command man pages are typically created in:
/usr/local/share/man/man1
If you prefer to create man pages in a different directory edit:
/private/etc/man.conf
Then add the new path to MANPATH_MAP, for example:
MANPATH_MAP /usr/local/bin /usr/local/man
To have man search a non-default path with a default fallback (/usr/local/share/man):
MANPATH /usr/local/man
MANPATH /usr/local/share/man
MANPATH_MAP /usr/local/bin /usr/local/share/man

Manual pages in MacOS X
The man command in MacOS X uses a sophisticated method of finding manual page files, based on the invocation options and environment variables, the /private/etc/man.conf configuration file, and some built in conventions and heuristics.
In MacOS X you have a command:
/usr/bin/manpath
That lists all your current locations for searching for man pages.
It can be invoked by just typing
manpath
in a Terminal.
It does not however add this to your $MANPATH shell variable.
But you'll still have access to the manpages with the man command.
What get's included in manpath is defined in
/private/etc/man.conf
It's not advised to export an environment variable called MANPATH without adding the output of:
`manpath`
to the list.
So if you want to export $MANPATH to your shell environment, do it like:
export MANPATH="`manpath`:/path/to/man/pages/to/include"
That way you'll get a complete list of manpages defined by the OS and any paths you add yourself.
For more info, open up a terminal and check:
man manpath
and the man.conf file with:
more /private/etc/man.conf
Usually a better option for including man pages in peculiar places, is to create a symlink to the directory containing the man pages in /usr/local/share/man which is indexed by the "man ecosystem" by default.

I had installed packages via brew, but the man command was drawing a blank because I had installed brew to a different directory.
To get round this, still linking the packages (which linked content up a few directories), I could then add to MANPATH in my .bash_profile, like so...
MANPATH="/Users/me/Developer/share/man:$MANPATH"

While existing answers do provide some hints/options which can help solve the OP's problem, they do not actually answer the question in title.
Indeed, in order for the man program to open the man page, it should know where to look for it. This is an obvious statement, but it doesn't help much. The question is whether you should use some "standard" location (and if so, what are those "standard" lookup paths, and where are they defined), or should you place the man page along with your program, and somehow point the man program to your custom location?
The OP seems to have tried placing the man page to what he thought was a "standard" location (/usr/local/man), but the man was unaware of it.
It should have worked if, instead of /usr/local/man/man1/custom_command.1, a /usr/local/share/man/man1/custom_command.1 was used. How could you know this? The answer is in the /etc/man.conf:
#
# Every automatically generated MANPATH includes these fields
#
MANPATH /usr/share/man
MANPATH /usr/local/share/man
MANPATH /usr/X11/man
MANPATH /Library/Apple/usr/share/man
/etc/man.conf is used to configure the default manpath (the provided example is from the default man.conf in macOS Big Sur). That being said, I don't think relying on man.conf default configuration and simply copying the man page for your custom program/script to one of these directories is the right thing to do.
The reason is that the default manpath is configured according to the man.conf only if the $MANPATH environment variable is not set or is empty. If the $MANPATH environment variable is set/not empty, the paths in the /etc/man.conf are not used to look up the man pages.
By default, $MANPATH is not set. But if your program/script + man page will be distributed to other users, you can't be sure whether or not it's set there.
So, what would be a reliable solution? In my opinion, shipping the man pages along with the script, and using the path_helper (man path_helper for more info) to point man to the custom manpath is the best way to go for third-party programs.
From the program/script author the only thing that's needed is to place the file, containing the path to the program man pages, into the /etc/manpaths.d directory. path_helper should do the rest.
It seems that path_helper was designed specifically for such use case, and it's being used by third-party programs (I learned about it after installing Wireshark and while trying to make its man pages discoverable), but there is one caveat:
path_helper will not make the man aware about your custom manpath, if the $MANPATH environment variable was not previously set (and as we know, it's not set by default). From path_helper man page:
(The MANPATH environment variable will not be modified unless it is already set in the environment.)
And this is the reason why you would actually want to set the $MANPATH, to allow the path_helper to augment it with custom manpaths afterwards.
In my case I added export MANPATH (just to set it, without any value) to /etc/zshenv (I am using macOS Big Sur, zsh is the default shell), and path_helper successfully added all the custom manpaths from /etc/manpaths.d files.

Besides all the entries pointed out in baf's answer, there's also /etc/manpaths, which is quite convenient to use for including man pages installed via Homebrew.
For example, below is the content of my /etc/manpaths:
/usr/local/opt/coreutils/libexec/gnuman
/usr/local/opt/findutils/libexec/gnuman
/usr/local/opt/gawk/libexec/gnuman
/usr/local/opt/gnu-sed/share/man
/usr/local/opt/readline/share/man
/usr/local/share/man
/usr/share/man
Meanwhile make sure in /etc/profile, MANPATH is defined before path_helper is loaded:
export MANPATH= # hack: path_helper doesn't setup MANPATH without this
eval `/usr/libexec/path_helper -s`
BTW, in macOS, the default pager is /usr/bin/less is a bit old, and doesn't even support \b for word boundary in regex, so you might want to setup MANPAGER in ~/.bashrc (or somewhere you prefer):
export MANPAGER=/usr/local/bin/less

Related

Git bash in Windows: change the default directory when opening mintty (pwd)

I am loosing a lot of time searching in internet for the following simple setting.
I installed git (and git bash) in Windows. What I want is just to open Git Bash and be in the directory I want. I don't want to change my home directory, just be in a given directory when I open the program.
More detailed, when I open Mingw / Git bash in Windows, I would like to be in the following folder:
/c/blabla/my_git_repositories
(this corresponds to the windows-style path: C:\blabla\my_git_repositories).
At the moment, I must write the following command every time I open GitBash:
cd /c/blabla/my_git_repositories
is this possible? Which file should i modify?
Actually the program is installed here:
C:\Program Files\Git\mingw64
Thanks
If you want it happening every time you start an interactive shell, add
cd /c/blabla/my_git_repositories
to your shell startup. If your install includes the manpages say man bash and find the INVOCATION section, in a decent pager just /^INV will do it. Or Google knows to interpret a search for man bash as a search for the bash manpage.
Windows doesn't ordinarily support shell logins at all so a lot of the shell's startup-circumstance detection is overkill on Windows. Executing it is extremely fast, but describing exactly how it decides takes a page or two.
The short form is, if the startup was told it's a login shell it reads the login startup files, including (your) ~/.bash_profile, which generally should check for an interactive login and if so source the normal interactive shell startup ~/.bashrc, so ~/.bash_profile should end with something like
[[ $- = *i* && -f ~/.bashrc ]] && . ~/.bashrc
and put whatever you want in ~/.bashrc. That cd, set up your prompt colors, define your favorite shell aliases, add your personal scripts directory to PATH, whatever.
Partial solution when opening the program by clicking on a link.
Right click on the link → properties → Start in: set the value to "C:\blabla\my_git_repositories".
This will work only when you open the application from that link, but could be fine (depending by your needs).

Where default PATH environment variable is defined

I've written a simple experiment which consists of cpp and shell. The main thing that cpp does is execve("./test.sh", NULL, NULL);, and shell tries to output environment variables as follows:
printenv
echo "PATH: $PATH"
It's quite expected that the environment is empty since I've sent no environment variables, but I get the following output:
PWD=/home/user/code/security_playground/display_path
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
So, first of all, the environment is not empty. Thus, the first question is how the environment is populated? What are defaults and minimal environment you could possibly get and where is it defined (if defined in config, etc.)?
Second question is where did PATH emerge from. It's not printed by printenv, but it's there if I print it with echo, and test.sh is still capable of calling utilities. Brief googling gave me an idea of /etc/environment, but it's contents is different:
└─$ cat /etc/environment
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
Which, by the way, is surprisingly empty. Why?
I do realize that much of that should be somewhere in docs, but all my googling lead me to quite generic environment descriptions, so any answers or search hints are welcome.
Where default PATH environment variable is defined
It depends. On the distribution, on the shell, on the environment, on OS, on configuration files.
I have some systems at hand, I see:
ArchLinux adds to PATH in /etc/profile.
OpenSuSE has yet a different code that adds to PATH from /etc/profile
CentOS7 has has yet a different code in /etc/profile
I suspect that each distribution places files in slightly different places, they will ship with slightly different configuration.
how the environment is populated?
Bash has DEFAULT_PATH_VALUE that is used when PATH is not set. But don't look at the default value too much - package distrbutors overwrite it.
There is /etc/environment (and pam_env.conf) that are read by PAM on login. So when you login. But not when you chroot.
The is /etc/profile and ~/.profile files read by the shell. These scripts may read other files. So usually there is drop-in dir /etc/profile.d/*.
In bash there is /etc/bashrc or /etc/bash.bashrc /etc/bash.login /etc/bash.logout or similar and user configuration files ``~/.bashrcetc. In bash also/etc/bash_completion.dand all scripts in/usr/share/bash_completionare also sourced, when completion is enabled. BUT these files are for Bourne shell - there are also other shells, notablyzshandcsh`, and people use them and they have different syntax and different set of startup files.
Each of these scripts can manipulate PATH, it can reset it, append to it, do whatever it wants to it.
And there are also different set of files read on login/non-login + interactive/non-interactive shells, and these files can include each other (it's common to have .bash_profile or other files that just source .bashrc or similar).
What are defaults
The /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin looks like a good default that should be safe on any linux.
by the way, is surprisingly empty. Why?
My /etc/environment file is just empty and has only the default comment in linux-pam package. /etc/environment has a very simple syntax and is read by pam (there may be no pam on your system...). To modify shell environment, one would prefer shell files - so /etc/profile is the place to keep system modifications. Also /etc/environment has simple key=value syntax, wherea's in /etc/profile you have, well, shell. And /etc/environment is read on login by PAM - so putting PATH just there would break I think for example docker, it just runs a shell in chroot, there is login.
To quote the POSIX specification:
If PATH is unset or is set to null, the path search is implementation-defined.
One way way an implementation can behave when PATH is initially unset is to simply set it to a hardcoded value. (It could also refuse to run any external executables at all, or throw monkeys at your face; "implementation defined" means the standard takes no position on what the computer does in the circumstance at hand, so it's unwise to make any assumption about what that behavior will be).
Similarly, for PWD, with emphasis added:
The value is set by the cd utility, and by the sh utility during initialization
...so initializing this at shell startup time is explicitly mandated by the standard.

Load .bash_profile for every terminal

I set up some aliases in my .bash_profile on my Max OS X.
It works but when I'm opening a new tab I always have to load my .bash_profile file with this command:
source ~/.bash_profile
How can I make it work for every terminal I'm opening, even if I'm restarting my Mac or Linux computer?
If you use zsh , you can add source ~/.bash_profile
at the end of .zshrc file at the following path: /Users/YOUR USER NAME/.zshrc , then restart your Terminal/iTerm2 app.
Note that this file is hidden. You can press CMD + SHIFT + . in Finder to
see it, Or just open it in default text editor with the following command from terminal:
open ~/.zshrc
Update
You don't need to do this by hand, run the following command:
echo "source ~/.bash_profile" >> ~/.zshrc
* Dont forget to restart your terminal.
The files executed at the start may be several, usually ~/.bashrc for interactive, non-login shells. The kind I assume you are using.
If so, create an ~/.bashrc file and source ~/.bash_profile in it:
if [ -f ~/.bash_profile ]; then
. ~/.bash_profile
fi
This web site has a lot of information about this.
Study this image, as it is a condensed guide
If you do need to find out exactly which file is being executed, take a look at this web page. It has a lot of specific tests to find out what file is setting what.
Specific for Mac-OS (which is an exception and loads ~/.bash_profile) do as is recomended in the site linked in this answer AFTER you confirm that your bash is doing as explained there.
I know this is a pretty old post, but this problem comes and goes quite oftenly and a lot of laborous solutions are offered. The fact is: being aware of a simple info would solve this pretty fast and easy:
LINUX/Unix OS will load the profile files on startup following the rules below (some distros may have other files names, mainly for user local profiles, but the main rule follows this):
Login Shell
First and foremost: /etc/profile is loaded (global settings);
Next: ˜/.bash_profile (local user settings- other files may be found, like ˜/.profile, depending on the distro. Check documentation).
So, if you are in a Login Shell environment, put all your crazy stuff inside ˜/.bash_profile (or the file provided by your distro) and everything will be fine.
Non-login Shell
First and foremost: /etc/bashrc (some distros will load bash.bashrc);
The next file to be seeked and loaded is ˜/.bashrc
And that's why so many people (just like me) got frustrated having to source their ˜/.bash_profile every single time a Terminal was loaded. We were simply inserting info in the "wrong" file- regarding the kind of shell loaded (see above: login, non-login).
More details on variants of the files mentioned above and some info on login vs non-login shell can be found here.
Hope it helps \o/

Setting environment variables in Yosemite

What is the proper way to modify environment variables like PATH in Yosemite?
This is this question Setting environment variables in OS X? but specifically for yosemite since it doesn't work anymore.
Have you tried editing ~/.bash_profile?
Adding a line like this to bash_profile ought to do it:
export PATH=/usr/local/bin:$PATH
What shell are you using? I'm assuming you're using the default Bash shell. There's also Csh, Ksh, and Zsh.
The Terminal.app on Mac OS X by default starts a new login shell each time a window is open. This means that $HOME/.bash_profile or $HOME/profile is always executed when you open a new terminal window. You can set particular defaults in here. For example, I set PS1 and set -o vi.
NOTE: This may not be the case if you're using other Terminal apps like xterm. These open new terminal windows as just new shells. This means that you may not see the changes made in .bash_profile until you log out and log back in.
You can try editing $HOME/.bashrc and see if that helps.
What about other shells?
If you're using Kornshell (ksh), you need to edit the $HOME/profile and not $HOME/.bash_profile. If you're using Zshell (zsh), you're on your own. It's too wacky to describe here. Read the manpage for zsh and search for ZDOTDIR.
When you run a shell script, the $HOME/.bashrc is executed. Most people put something like this in their .bash_profile, so their .bashrc settings are included in a new terminal window:
[[ -x $HOME/.bashrc ]] && source "$HOME/.bashrc"
Some people set things they want to be set when they run a shell script, for example export $PS4="\$LINENO> ".
The $PATH is a bit different. You can set it in .bash_profile (I would not set it in .bashrc), But, Mac OS X has an automated why on how systemwide paths are set. A file called /etc/paths is used to set the default path for all users using either Bash or Kornshell via the /usr/libexec/path_helper program.
On my Mac, I set my $PATH to:
/usr/local/bin:/usr/share/bin:/bin:/usr/bin:/usr/sbin:/sbin:$HOME/bin
When I install programs, I usually install them under /opt when possible. Then, I link their binaries (where ever they're placed) to /usr/local/bin. This way, I don't have to keep building my PATH. Plus, it allows me to override system defaults. For example, /usr/bin/git is at 1.9.3. while my installed /usr/local/bin/git is at version 2.2.1.
One thing you should not do is modify /etc/profile because changes there may be replaced on OS X upgrades.
The problem is not with environment variables set and accessed from within /bin/bash or /bin/sh, but with envars that should be set for programs NOT executed from the shell; i.e. normal apps executed from the dock or Finder.
After finally getting things right with launchctl in Mavericks, Apple is in the process of changing things again. The useful subcommands of launchctl are now labelled as "legacy subcommands", some of which are no longer supported. That leaves a question mark over the others.
In any case, the most important subcommands are still available for now.
launchctl allows for the setting of the overall environment in which user processes execute. It appears that the overall user environment is inherited by all Terminal processes; i.e. all setenv variables are exported. It's a bit tricky to confirm that. In any case, you will still need your .profile and .bashrc to define functions and aliases, which are not supported by launchctl.
I go to some lengths to ensure that all of my launchctl vars are also defined in my profile. This enables me to set up the same environment on remote or VM linux systems, with a few minor tweaks.
Al of my setup is described in this blog post .
following solution worked for me.
Open Terminal
Click on Terminal Menu at right upper corner.
click on Preferences
Click on General
Change Shell open with to command and put /bin/bash in text box.
Now whatever configuration you do in ~/.bash_profile takes effect. Previously you were not using bash(were using ksh) that is why it was not reading .bash_profile.

Where to place $PATH variable assertions in zsh?

I love zsh, but I am not sure where to place my $PATH and other variable assertions? I find that they are scattered between the files .zshrc .zprofile .bashrc .bash_profile, and sometimes doubled.
I realize that having anything inside the bash files doesn't make much sense seeing as I'm using zsh, but where exactly should I be placing my rvm, python, node etc additions to my $PATH?
Is there a specific file I should be using (i.e. .zshenv which does not currently exist in my installation), one of the ones I am currently using, or does it even matter?
tl;dr version: use ~/.zshrc
And read the man page to understand the differences between:
~/.zshrc, ~/.zshenv and ~/.zprofile.
Regarding my comment
In my comment attached to the answer kev gave, I said:
This seems to be incorrect - /etc/profile isn't listed in any zsh documentation I can find.
This turns out to be partially incorrect: /etc/profile may be sourced by zsh. However, this only occurs if zsh is "invoked as sh or ksh"; in these compatibility modes:
The usual zsh startup/shutdown scripts are not executed. Login shells source /etc/profile followed by $HOME/.profile. If the ENV environment variable is set on invocation, $ENV is sourced after the profile scripts. The value of ENV is subjected to parameter expansion, command substitution, and arithmetic expansion before being interpreted as a pathname. [man zshall, "Compatibility"].
The ArchWiki ZSH link says:
At login, Zsh sources the following files in this order:
/etc/profile
This file is sourced by all Bourne-compatible shells upon login
This implys that /etc/profile is always read by zsh at login - I haven't got any experience with the Arch Linux project; the wiki may be correct for that distribution, but it is not generally correct. The information is incorrect compared to the zsh manual pages, and doesn't seem to apply to zsh on OS X (paths in $PATH set in /etc/profile do not make it to my zsh sessions).
To address the question:
where exactly should I be placing my rvm, python, node etc additions to my $PATH?
Generally, I would export my $PATH from ~/.zshrc, but it's worth having a read of the zshall man page, specifically the "STARTUP/SHUTDOWN FILES" section - ~/.zshrc is read for interactive shells, which may or may not suit your needs - if you want the $PATH for every zsh shell invoked by you (both interactive and not, both login and not, etc), then ~/.zshenv is a better option.
Is there a specific file I should be using (i.e. .zshenv which does not currently exist in my installation), one of the ones I am currently using, or does it even matter?
There's a bunch of files read on startup (check the linked man pages), and there's a reason for that - each file has it's particular place (settings for every user, settings for user-specific, settings for login shells, settings for every shell, etc).
Don't worry about ~/.zshenv not existing - if you need it, make it, and it will be read.
.bashrc and .bash_profile are not read by zsh, unless you explicitly source them from ~/.zshrc or similar; the syntax between bash and zsh is not always compatible. Both .bashrc and .bash_profile are designed for bash settings, not zsh settings.
Here is the docs from the zsh man pages under STARTUP/SHUTDOWN FILES section.
Commands are first read from /etc/zshenv this cannot be overridden.
Subsequent behaviour is modified by the RCS and GLOBAL_RCS options; the
former affects all startup files, while the second only affects global
startup files (those shown here with an path starting with a /). If
one of the options is unset at any point, any subsequent startup
file(s) of the corresponding type will not be read. It is also possi-
ble for a file in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and
GLOBAL_RCS are set by default.
Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login
shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zpro-
file. Then, if the shell is interactive, commands are read from
/etc/zshrc and then $ZDOTDIR/.zshrc. Finally, if the shell is a login
shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.
From this we can see the order files are read is:
/etc/zshenv # Read for every shell
~/.zshenv # Read for every shell except ones started with -f
/etc/zprofile # Global config for login shells, read before zshrc
~/.zprofile # User config for login shells
/etc/zshrc # Global config for interactive shells
~/.zshrc # User config for interactive shells
/etc/zlogin # Global config for login shells, read after zshrc
~/.zlogin # User config for login shells
~/.zlogout # User config for login shells, read upon logout
/etc/zlogout # Global config for login shells, read after user logout file
You can get more information here.
I had similar problem (in bash terminal command was working correctly but zsh showed command not found error)
Solution:
just paste whatever you were earlier pasting in ~/.bashrc to:
~/.zshrc

Resources