diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-16 19:49:35 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-16 19:49:35 +1200 |
commit | 6cbb1755813b9fd3ad016aafc202a36eda37718a (patch) | |
tree | d7d985980ef5fa78572f13b867d6b0bdfd9f3a24 /bin/rndl | |
parent | Apply suffix rules for games/bin building (diff) | |
download | dotfiles-6cbb1755813b9fd3ad016aafc202a36eda37718a.tar.gz dotfiles-6cbb1755813b9fd3ad016aafc202a36eda37718a.zip |
Reverse .m4 translation for binscripts
Either this is overengineering, or I don't understand m4 well enough.
Diffstat (limited to 'bin/rndl')
-rwxr-xr-x | bin/rndl | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/bin/rndl b/bin/rndl new file mode 100755 index 00000000..7d5cb6b7 --- /dev/null +++ b/bin/rndl @@ -0,0 +1,51 @@ +#!/bin/sh +# Print a random line from input +self=rndl + +# If there are no arguments, we're checking stdin; this is more complicated +# than checking file arguments because we have to count the lines in order to +# correctly choose a random one, and two passes means we require a temporary +# file if we don't want to read all of the input into memory (!) +if [ "$#" -eq 0 ] ; then + + # Create a temporary directory with name in $td, and handle POSIX-ish traps to + # remove it when the script exits. + td= + cleanup() { + [ -n "$td" ] && rm -fr -- "$td" + if [ "$1" != EXIT ] ; then + trap - "$1" + kill "-$1" "$$" + fi + } + for sig in EXIT HUP INT TERM ; do + # shellcheck disable=SC2064 + trap "cleanup $sig" "$sig" + done + td=$(mktd "$self") || exit + + # We'll operate on stdin in the temp directory; write the script's stdin to + # it with cat(1) + set -- "$td"/stdin + cat >"$td"/stdin +fi + +# Count the number of lines in the input +lc=$(sed -- '$=;d' "$@") || exit + +# If there were none, bail +case $lc in + ''|0) + printf 2>&1 'rndl: No lines found on input\n' + exit 2 + ;; +esac + +# Try to get a random seed from rnds(1) for rndi(1) +seed=$(rnds) + +# Get a random line number from rndi(1) +ri=$(rndi 1 "$lc" "$seed") || exit + +# Print the line using sed(1) +sed -- "$ri"'!d' "$@" |