diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2015-07-23 14:38:04 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2015-07-23 14:38:04 +1200 |
commit | 3ea08b5fb4e2062b14772ffea3476470c246907f (patch) | |
tree | bff2272bf79dbf73736600424144565ca61046cd /bash | |
parent | Remove a few unneeded quotes (diff) | |
download | dotfiles-3ea08b5fb4e2062b14772ffea3476470c246907f.tar.gz dotfiles-3ea08b5fb4e2062b14772ffea3476470c246907f.zip |
Add apf func (argument prepend [from] file)
Diffstat (limited to 'bash')
-rw-r--r-- | bash/bashrc.d/apf.bash | 100 |
1 files changed, 100 insertions, 0 deletions
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[@]}" "$@" +} + |