aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.markdown3
-rw-r--r--bash/bashrc.d/apf.bash99
-rwxr-xr-xbin/apf44
-rw-r--r--man/man1/apf.165
4 files changed, 111 insertions, 100 deletions
diff --git a/README.markdown b/README.markdown
index 7a29e0c5..20bf847b 100644
--- a/README.markdown
+++ b/README.markdown
@@ -184,7 +184,6 @@ I also add completions for my own scripts and functions where useful.
There are a few other little tricks in `bash/bashrc.d`, including:
-* `apf` prepends arguments to a command with ones read from a file.
* `bd` changes into a named ancestor of the current directory.
* `fnl` runs a command and save its output and error into temporary files.
* `hgrep` searches `$HISTFILE`.
@@ -309,6 +308,8 @@ Installed by the `install-bin` target:
* `rnda(1)` uses `rndi(1)` to choose a random argument
* `rndf(1)` uses `rnda(1)` to choose a random file from a directory
* `rndl(1)` uses `rndi(1)` to choose a random line from files
+* `apf(1)` prepends arguments to a command with ones read from a file,
+ intended as a framework for shell functions.
* `ax(1)` evaluates an awk expression given on the command line; this is
intended as a quick way to test how Awk would interpret a given expression.
* `bel(1)` prints a terminal bell character
diff --git a/bash/bashrc.d/apf.bash b/bash/bashrc.d/apf.bash
deleted file mode 100644
index 44de3a9e..00000000
--- a/bash/bashrc.d/apf.bash
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# apf -- arg-prepend-file -- Prepend null-delimited arguments read from a file
-# to a command's arguments before running it. This is intended as a way of
-# implementing *rc files for interactive Bash calls to programs that don't
-# support such files, without having to use broken environment variables (e.g.
-# GREP_OPTIONS); this enables you to, for example, use arguments with shell
-# metacharacters and spaces in them that you do not want expanded.
-#
-# For example, given this simple program in our $PATH, printargs:
-#
-# $ cat ~/.local/bin/printargs
-# #!/bin/sh
-# printf '%s\n' "$@"
-#
-# Which just prints its arguments:
-#
-# $ printargs a b c
-# a
-# b
-# c
-#
-# We could do this:
-#
-# $ printf '%s\0' -f --flag --option '? foo bar *' > "$HOME"/.printargsrc
-#
-# $ apf "$HOME"/.printargsrc printargs a b c
-# -f
-# --flag
-# --option
-# ? foo bar *
-# a
-# b
-# c
-#
-# We could then make a permanent wrapper function with:
-#
-# $ printargs() { apf "$HOME"/.printargsrc printargs "$@" ; }
-#
-# $ printargs a b c
-# -f
-# --flag
-# --option
-# ? foo bar *
-# a
-# b
-# c
-#
-# $ printf '%s\n' !-2:q >> "$HOME"/.bashrc
-#
-# This means you can edit the options in the *rc file and don't have to
-# redefine a wrapper function.
-#
-# If you actually want those options to *always* be added, regardless of
-# whether you're in an interactive shell, you really should make an actual
-# wrapper script.
-#
-apf() {
-
- # Require at least two arguments, give usage otherwise
- if (($# < 2)) ; then
- printf 'bash: %s: usage: %s ARGFILE COMMAND [ARGS...]\n' \
- "$FUNCNAME" "$FUNCNAME" >&2
- return 2
- fi
-
- # First argument is the file containing the null-delimited arguments
- local argfile=$1
- shift
-
- # Check the arguments file makes sense
- if [[ ! -e $argfile ]] ; then
- printf 'bash: %s: %s: No such file or directory\n' \
- "$FUNCNAME" "$argfile"
- return 1
- elif [[ -d $argfile ]] ; then
- printf 'bash: %s: %s: Is a directory\n' \
- "$FUNCNAME" "$argfile"
- return 1
- elif [[ ! -r $argfile ]] ; then
- printf 'bash: %s: %s: Permission denied\n' \
- "$FUNCNAME" "$argfile"
- return 1
- fi
-
- # Read all the null-delimited arguments from the file
- local -a args
- local arg
- while IFS= read -rd '' arg ; do
- args[${#args[@]}]=$arg
- done < "$argfile"
-
- # Next argument is the command to run
- local cmd=$1
- shift
-
- # Run the command with the retrieved arguments first, then the rest of the
- # command line as passed to the function
- command "$cmd" "${args[@]}" "$@"
-}
diff --git a/bin/apf b/bin/apf
new file mode 100755
index 00000000..2d137c6b
--- /dev/null
+++ b/bin/apf
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+# Name self
+self=apf
+
+# Require at least two arguments, give usage otherwise
+if (($# < 2)) ; then
+ printf '%s: usage: %s ARGFILE COMMAND [ARGS...]\n' \
+ "$self" "$self" >&2
+ 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
+
+# Read all the null-delimited arguments from the file
+declare -a args
+while IFS= read -rd '' arg ; do
+ args[${#args[@]}]=$arg
+done < "$argfile"
+
+# Next argument is the command to run
+cmd=$1
+shift
+
+# Run the command with the retrieved arguments first, then the rest of the
+# command line as passed to the function
+command "$cmd" "${args[@]}" "$@"
diff --git a/man/man1/apf.1 b/man/man1/apf.1
new file mode 100644
index 00000000..67b3b25a
--- /dev/null
+++ b/man/man1/apf.1
@@ -0,0 +1,65 @@
+.TH APF 1 "August 2016" "Manual page for apf"
+.SH NAME
+.B apf
+\- add arguments to a command from a file
+.SH SYNOPSIS
+.B apf
+foorc
+foo --bar baz
+.SH DESCRIPTION
+Add null-delimited arguments read from a file to a command's arguments before
+running it. This is intended as a way of implementing *rc files for interactive
+shell calls to programs that don't support such files, without having to use
+broken environment variables (e.g. GREP_OPTIONS); this enables you to, for
+example, use arguments with shell metacharacters and spaces in them that you do
+not want expanded.
+
+For example, given this simple program in our $PATH, printargs:
+
+ $ cat ~/.local/bin/printargs
+ #!/bin/sh
+ printf '%s\n' "$@"
+
+Which just prints its arguments:
+
+ $ printargs a b c
+ a
+ b
+ c
+
+We could do this:
+
+ $ printf '%s\0' -f --flag --option '? foo bar *' > "$HOME"/.printargsrc
+
+ $ apf "$HOME"/.printargsrc printargs a b c
+ -f
+ --flag
+ --option
+ ? foo bar *
+ a
+ b
+ c
+
+We could then make a permanent wrapper function with:
+
+ $ printargs() { apf "$HOME"/.printargsrc printargs "$@" ; }
+
+ $ printargs a b c
+ -f
+ --flag
+ --option
+ ? foo bar *
+ a
+ b
+ c
+
+ $ printf '%s\n' !-2:q >> "$HOME"/.bashrc
+
+This means you can edit the options in the *rc file, and don't have to redefine
+a wrapper function.
+
+If you actually want those options to *always* be added, regardless of whether
+you're in an interactive shell, you really should make an actual wrapper
+script.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>