aboutsummaryrefslogtreecommitdiff
path: root/bin/apf
diff options
context:
space:
mode:
Diffstat (limited to 'bin/apf')
-rwxr-xr-xbin/apf80
1 files changed, 46 insertions, 34 deletions
diff --git a/bin/apf b/bin/apf
index 06f7aa6b..956142fe 100755
--- a/bin/apf
+++ b/bin/apf
@@ -1,43 +1,55 @@
-#!/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
-# Require at least two arguments, give usage otherwise
-if (($# < 2)) ; then
- printf '%s: usage: %s ARGFILE COMMAND [ARGS...]\n' \
- "$self" "$self" >&2
+# 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
-
-# Check the arguments file makes sense
-if [[ ! -e $argfile ]] ; then
- printf '%s: %s: No such file or directory\n' \
- "$self" "$argfile"
- exit 1
-elif [[ -d $argfile ]] ; then
- printf '%s: %s: Is a directory\n' \
- "$self" "$argfile"
- exit 1
-elif [[ ! -r $argfile ]] ; then
- printf '%s: %s: Permission denied\n' \
- "$self" "$argfile"
- exit 1
-fi
+argf=$1 cmd=$2
+shift 2
+
+# 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
+
+ # 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
-# Read all the null-delimited arguments from the file
-declare -a args
-while IFS= read -rd '' arg ; do
- args[${#args[@]}]=$arg
-done < "$argfile"
+ # Write the arguments in reverse to a temporary file
+ revf=$td/revf
+ sed '1!G;$!{h;d}' "$argf" > "$revf" || exit
-# Next argument is the command to run
-cmd=$1
-shift
+ # 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"
+
+ # We can remove the temporary stuff now, which allows us to exec safely
+ cleanup
+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" "$@"