aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2016-08-19 15:59:46 +1200
committerTom Ryder <tom@sanctum.geek.nz>2016-08-19 16:00:35 +1200
commit475e31ca38054b5abb51fc4eae7c654fe573b72d (patch)
tree6a8e9696ffa4ca564939dff329605593a794c533 /bin
parentCorrect stws(1)'s self-identifying (diff)
downloaddotfiles-475e31ca38054b5abb51fc4eae7c654fe573b72d.tar.gz
dotfiles-475e31ca38054b5abb51fc4eae7c654fe573b72d.zip
Translate apf(1) to POSIX sh
We lose the ability to include newlines in options, but probably a pretty good tradeoff, especially since it makes the *rc files hand-editable in theory. Also add skipping comments and blank lines. Update ISSUES.markdown. There are two more Bash scripts left; one of them, han(1), does actually require Bash, though.
Diffstat (limited to 'bin')
-rwxr-xr-xbin/apf62
1 files changed, 42 insertions, 20 deletions
diff --git a/bin/apf b/bin/apf
index 733d67fc..0a0cbeea 100755
--- a/bin/apf
+++ b/bin/apf
@@ -1,30 +1,52 @@
-#!/usr/bin/env bash
-# Prepend arguments from a file to a command call
+#!/bin/sh
+# Prepend arguments from a file to the given arguments for a command
self=apf
-# Give up completely if no BASH_VERSINFO (<2.0)
-[ -n "$BASH_VERSINFO" ] || exit
-
-# Require at least two arguments, give usage otherwise
-if (($# < 2)) ; then
+# Require at least two arguments
+if [ "$#" -lt 2 ] ; then
printf >&2 '%s: Need an arguments file and a command\n' "$self"
exit 2
fi
# First argument is the file containing the null-delimited arguments
-argfile=$1
-shift
+argf=$1 cmd=$2
+shift 2
-# Read all the null-delimited arguments from the file
-declare -a args
-while IFS= read -rd '' arg ; do
- args[${#args[@]}]=$arg
-done < "$argfile"
+# If the file exists, we'll read it. If it doesn't, this is not an error (think
+# personal config files like ~/.vimrc)
+if [ -f "$argf" ] ; then
-# Next argument is the command to run
-cmd=$1
-shift
+ # 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
+
+ # Write the arguments in reverse to a temporary file
+ revf=$td/revf
+ sed '1!G;$!{h;d}' "$argf" > "$revf" || exit
+
+ # Stack up all the arguments from the file. Skip blank lines and comments.
+ # An empty file is also fine.
+ while IFS= read -r arg ; do
+ case $arg in
+ '#'*) continue ;;
+ *[![:space:]]*) ;;
+ *) continue ;;
+ esac
+ set -- "$arg" "$@"
+ done < "$revf"
+fi
-# Run the command with the retrieved arguments first, then the rest of the
-# command line as passed to the function
-command "$cmd" "${args[@]}" "$@"
+# Run the command with the changed arguments
+exec "$cmd" "$@"