shdoc
June 2, 2026 ยท View on GitHub
shdoc is a documentation generator for bash/zsh/sh for generating API documentation in Markdown from shell scripts source.
shdoc parses annotations in the beginning of a given file and alongside function definitions, and creates a markdown file with ready to use documentation.
Index
Example
|
Generate documentation with the following command:
Source examples/readme-example.sh
|
|
Features
@name
A name of the project, used as a title of the doc. Can be specified once in the beginning of the file.
Example
#!/usr/bin/env bash
# @name MyLibrary
@file
Identical to @name.
@brief
A brief line about the project. Can be specified once in the beginning of the file.
Example
#!/usr/bin/env bash
# @brief A library to solve a few problems.
@description
A multiline description of the project/section/function.
- Can be specified once for the whole file in the beginning of the file.
- Can be specified once for a section of the file. See @section.
- Can be specified once for on top of a function definition.
Example
#!/usr/bin/env bash
# @description A long description of the library.
# Second line of the project description.
# @description My super function.
# Second line of my super function description.
function super() {
...
}
@deprecated
Whether or not the function is deprecated. If it is, a short deprecation notice will be prepended to the description.
Example
# @deprecated
say-hello() {
...
}
@section
The name of a section of the file. Can be used to group functions.
Example
# @section My utilities functions
# @description The following functions can be used to solve problems.
@example
A multiline example of the function usage. Can be specified only alongside the function definition.
Example
# @example
# echo "test: $(say-hello World)"
say-hello() {
...
}
@option
A description of an option expected to be passed while calling the function.
Can be specified multiple times to describe any number of arguments.
If an option argument is expected, it must be specified between < and >
Example
# @description Says hi to a given person.
# @option -h A short option.
# @option --value=<value> A long option with argument.
# @option -v<value> | --value <value> A long option with short option alternative.
say-hello() {
...
}
@arg
A description of an argument expected to be passed while calling the function. Can be specified multiple times to describe any number of arguments.
Example
# @description Says hi to a given person.
# @arg \$1 string A person's name.
# @arg \$2 string Message priority.
say-hello() {
...
}
@noargs
A note that the function does not expect any arguments to be passed.
Example
# @description Says 'hello world'.
# @noargs
say-hello-world() {
...
}
@set
A description of a global variable that is set while calling the function. Can be specified multiple times to describe any number of variables
Example
# @description Sets hello to the variable REPLY
# @set REPLY string Greeting message.
set-hello() {
...
}
@exitcode
Describes an expected exitcode of the function. Can be specified multiple times to describe all possible exitcodes and their conditions.
Example
# @description Says 'hello world'.
# @exitcode 0 If successful.
# @exitcode 1 If world is gone.
say-hello-world() {
...
}
@stdin
The expected input to the function call from stdin (usually the terminal or command line)
Example
# @description Asks name.
# @stdin The users name from the terminal/command line.
say-hello-world() {
...
}
@stdout
An expected output of the function call.
Example
# @description Says 'hello world'.
# @stdout A path to a temporary file with the message.
say-hello-world() {
...
}
@stderr
An expected output of the function call on /dev/stderr.
Example
# @description Says 'hello world'.
# @stderr A error message when world is not available.
say-hello-world() {
...
}
@see
Create a link on the given function in the "See Also" section.
Example
# @see say-hello
# @see text with [markdown link](./other-file#other-function)
say-hello-world() {
...
}
@internal
When you want to skip documentation generation for a particular function, you can specify this
@internal tag.
It allows you to have the same style of doc comments across the script and keep internal
functions hidden from users.
Example
# @internal
show-msg() {
...
}
Usage
shdoc expects a shell script with comments on stdin and produces markdown on stdout.
$ shdoc < your-shell-script.sh > doc.md
You can also pass an input file directly:
$ shdoc your-shell-script.sh > doc.md
Display command-line help with --help or -h:
$ shdoc --help
Display version information with --version:
$ shdoc --version
Installation
Arch Linux
Arch Linux users can install shdoc using package in AUR: shdoc-git
Fedora & EPEL
Fedora and EPEL releases ship the shdoc package:
dnf install shdoc
Using Git
NOTE: shdoc requires gawk: apt-get install gawk
git clone --recursive https://github.com/reconquest/shdoc
cd shdoc
sudo make install
Others
Unfortunately, there are no packages of shdoc for other distros, but we're looking for contributions.
Vim syntax highlighting
shdoc includes Vim syntax highlighting for annotations in shell files. With vim-plug, add this to your Vim configuration:
call plug#begin('~/.vim/plugged')
Plug 'reconquest/shdoc', { 'rtp': 'contrib/vim' }
call plug#end()
Then run:
:PlugInstall
The syntax file is loaded as an after/syntax/sh.vim file, so it extends Vim's normal shell highlighting.
Examples
See example documentation on:
LICENSE
MIT