From 3ea08b5fb4e2062b14772ffea3476470c246907f Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Thu, 23 Jul 2015 14:38:04 +1200 Subject: Add apf func (argument prepend [from] file) --- bash/bashrc.d/apf.bash | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 bash/bashrc.d/apf.bash (limited to 'bash') diff --git a/bash/bashrc.d/apf.bash b/bash/bashrc.d/apf.bash new file mode 100644 index 00000000..af759577 --- /dev/null +++ b/bash/bashrc.d/apf.bash @@ -0,0 +1,100 @@ +# +# 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 read -d '' -r 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[@]}" "$@" +} + -- cgit v1.2.3