diff options
Diffstat (limited to 'bin/apf')
-rwxr-xr-x | bin/apf | 80 |
1 files changed, 46 insertions, 34 deletions
@@ -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" "$@" |