From 475e31ca38054b5abb51fc4eae7c654fe573b72d Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 19 Aug 2016 15:59:46 +1200 Subject: 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. --- bin/apf | 62 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 20 deletions(-) (limited to 'bin') 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" "$@" -- cgit v1.2.3