#!/usr/bin/env bash__options="--name|-n Set name.--greet-msg Set greet message.\nDefault is 'Hello'."# Default parameters__name="Alice"__greet_msg="Hello"# Non sub command_hello(){echo"$__greet_msg$1!"}# sub commandsgreet(){# Call the _hello function,# passing the value of the $__name variable._hello"$__name"}commands(){# Show subcommands.echo"$__subcommands"}# Functions for help_print_explain(){localvalue="$1"localspaces="$2"localname_length="$3"localcomments="$4"localprefix=$(printf"%${spaces}s%-${name_length}s%s\n""""$value ")whileIFS=read-rline;doprintf"%s%s\n""$prefix""$line"prefix="${prefix//?/ }"done<<<"$comments"}_extract_comments(){localfunc="$1"awk"/^${func} \(\)/{flag=1;next}/^}/{flag=0}flag""$0"|awk'/^ *#/{sub(/^ *# ?/, ""); print; next} {exit}'}_print_subcommands(){echo"Subcommands:"forfuncin$__subcommands;dolocalcomments=$(_extract_comments"$func")_print_explain"$func"235"$comments"done}_print_options(){echo"Options:"localline
echo"$__options"|whileread-rline;doif[-z"$line"];thencontinuefilocalopt="$(echo"${line%% *}"|sed's/|/, /g')"localcomment="$(echo-e"${line#* }")"_print_explain"$opt"235"$comment"done_print_explain"--help, -h"235"Show help."}help(){# Show this help.echo"Usage $0 <subcommand> [options]"echo""_print_subcommands
_print_options
}# Generate options parser_generate_read_options(){cat<< EOF_read_options() { __positional=() while [[ \$# -gt 0 ]]; do if [ "\$1" = "--" ]; then shift __positional+=("\$@") break fi local opt="\${1//_/-}" case \$opt inEOFecho"$__options"|whileread-rline;doif[-z"$line"];thencontinuefilocalopt=$(echo"$line"|awk'{print $1}')localval_name=$(echo"${opt//-/_}"|cut-d'|'-f1)echo" $opt) ${val_name}=\"\$2\"; shift; shift;;"donecat<< EOF --help|-h) help; exit;; -*) echo "Unknown option: \$1" 1>&2 exit 1 ;; *) if [ "\$1" = "help" ]; then help exit fi __positional+=("\$1") shift ;; esac done}EOF}# Start main# Make sub command list__subcommands=$(set|grep-v"^_"|grep-v"^ "|grep" () $"|cut-d' '-f1|tr'\n'' ')# No argumentsif[$#-eq0];thenhelpfi# Read argumentseval"$(_generate_read_options)"_read_options"$@"# Check sub command__subcommand="${__positional[0]}"shiftif!echo" $__subcommands "|grep-q" $__subcommand ";thenecho"$__subcommand is unknown subcommand."echo""helpexit1fi# Run sub command$__subcommand
これを実行してみると、
1234567891011121314151617181920212223242526
$ ./my_command.sh
Usage ./my_command.sh <subcommand> [options]
Subcommands:
commands Show subcommands.
greet Call the _hello function,
passing the value of the $__name variable.
help Show this help.
Options:
--name, -n Set name.
--greet-msg Set greet message.
Default is 'Hello'.
--help, -h Show help.
$ ./my_command.sh commands
commands greet help
$ ./my_command.sh greet
Hello Alice!
$ ./my_command.sh greet --name Bob --greet-msg "Good morning"
Good morning Bob!
$ ./my_command.sh greet --name 太郎君 --greet-msg "こんにちは"
こんにちは 太郎君!
$ ./my_command.sh greet -n 太郎君 --greet-msg "こんにちは"
こんにちは 太郎君!
$ ./my_command.sh greet -n 太郎君 -g "こんにちは"
Unknown option: -g
$