-
-
Save kovetskiy/a4bb510595b3a6b17bfd1bd9ac8bb4a5 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
### | |
### my-script — does one thing well | |
### | |
### Usage: | |
### my-script <input> <output> | |
### | |
### Options: | |
### <input> Input file to read. | |
### <output> Output file to write. Use '-' for stdout. | |
### -h Show this message. | |
help() { | |
sed -rn 's/^### ?//;T;p' "$0" | |
} | |
if [[ $# == 0 ]] || [[ "$1" == "-h" ]]; then | |
help | |
exit 1 | |
fi | |
echo Hello World |
This doesn't actually work cross-platform, the -r
option does not exist on macOS. You can do the same with awk
though, just use:
awk '/^###/' "$0"
Complete script:
#!/bin/bash
###
### my-script — does one thing well
###
### Usage:
### my-script <input> <output>
###
### Options:
### <input> Input file to read.
### <output> Output file to write. Use '-' for stdout.
### -h Show this message.
help() {
awk '/^###/' "$0"
}
if [[ $# == 0 ]] || [[ "$1" == "-h" ]]; then
help
exit 1
fi
echo Hello World
This doesn't actually work cross-platform, the
-r
option does not exist on macOS. You can do the same withawk
though, just use:
Install GNU coreutils
and gnu-sed
on MacOS using brew install coreutils gnu-sed
if you want to get closer to Linux.
awk '/^###/' "$0"
awk -F'### ' '/^###/' "$0"
That's cool but I think I'll stick with here documents.
#!/bin/bash
Help=$(cat <<-"HELP"
my-script — does one thing well
Usage:
my-script <input> <output>
Options:
<input> Input file to read.
<output> Output file to write. Use '-' for stdout.
-h Show this message.
HELP
)
help() {
echo "$Help"
}
if [[ $# == 0 ]] || [[ "$1" == "-h" ]]; then
help
exit 1
fi
echo Hello World
This is a really nifty approach, thanks for sharing. It's fairly obvious in retrospect but it hadn't occurred to me before!
Slight tweak, this awk solution will only print the help text, not the leading ###
:
awk -F'### ' '/^###/ { print $2 }' "$0"
Compacted:
[[ $# == 0 || "$1" == "-h" ]]
This doesn't actually work cross-platform, the
-r
option does not exist on macOS. You can do the same withawk
though, just use:
awk '/^###/' "$0"
Complete script:
#!/bin/bash ### ### my-script — does one thing well ### ### Usage: ### my-script <input> <output> ### ### Options: ### <input> Input file to read. ### <output> Output file to write. Use '-' for stdout. ### -h Show this message. help() { awk '/^###/' "$0" } if [[ $# == 0 ]] || [[ "$1" == "-h" ]]; then help exit 1 fi echo Hello World
or you can use gsed
, if you don't want to pollute the macos sed
namespace
A sh
compatible version, with portable sed
usage
#!/bin/sh
###
### my-script — does one thing well
###
### Usage:
### my-script <input> <output>
###
### Options:
### <input> Input file to read.
### <output> Output file to write. Use '-' for stdout.
### -h Show this message.
help() {
sed -n 's/^### \?//p' "$0"
}
if [ $# -eq 0 ] || [ "$1" = "-h" ]; then
help
exit 1
fi
echo Hello World
Complete awk version:
#!/usr/bin/env bash
###
### my-script — does one thing well
###
### Usage:
### my-script <input> <output>
###
### Options:
### <input> Input file to read.
### <output> Output file to write. Use '-' for stdout.
### -h Show this message.
help() {
awk -F'### ' '/^###/ { print $2 }' "$0"
}
if [[ $# == 0 || "$1" == "-h" ]]; then
help
exit 1
fi
echo Hello World
I personally use macros to add help messages to my zsh functions. It's as easy as:
mdoc-test() {
# uses the global alias MAGIC
mdoc Usage: sth MAGIC
echo no
}
mdoc-test2() {
# without global alias
magic mdoc Usage: sth ; mret
echo no
}
Awesome idea, thanks very much!
Very cool.
That's a good idea. Awesome!
Glad someone proved this is a good strategy to write helper message, I also did it in my commonly-used script:
https://gist.github.com/typebrook/b0d2e7e67aa50298fdf8111ae7466b56#file-gist
what I did is simply print the comment at the top(except the first line to # --
):
sed -Ene "/^#/ !q; 1,/^# --/ d; s/^# //p
This doesn't actually work cross-platform, the
-r
option does not exist on macOS. You can do the same withawk
though, just use:
-E
works on BSD sed, so you can make it portable with sed -Ene 's/^### ?//;T;p' "$0"
both on mac(BSD sed) or Linux(GNU sed).
666
Why even use the extended version?
sed -n 's/^###//p'
achieves the same. Just keep the leading ###
format to the help only.
sed -n '/^###/ s///p'
this one's faster but a tiny bit more verbose.
and sed '/^###/!d'
if you don't mind hashes. Or grep "^###"
My version, that doesn't require multiple #
(but allows more than one if you want it for stylistic reasons):
#!/bin/bash
# Usage:
# test_usage.sh ...
print_usage_and_exit() {
# The sed script below:
# - Deletes the first line (shebang).
# - Quits on the first line that doesn't start with #.
# - Removes the '#+ ?' prefix from the string.
sed -En '1d; /^[^#]/ q; s/^#+ ?//p;' < "$0" >&2
exit 1
}
This. Is. Perfect. 😍