diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2017-01-02 16:57:44 +1300 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2017-01-02 17:10:10 +1300 |
commit | 8904477c83d589db3e928a6c5a34d542b362de0b (patch) | |
tree | cf641232832feb5f67f630470bc8aa0623882507 | |
parent | Handle simple relative dirs in md() (diff) | |
download | dotfiles-8904477c83d589db3e928a6c5a34d542b362de0b.tar.gz dotfiles-8904477c83d589db3e928a6c5a34d542b362de0b.zip |
Add swr(1df)
-rw-r--r-- | README.markdown | 2 | ||||
-rwxr-xr-x | bin/swr | 65 | ||||
-rw-r--r-- | man/man1/swr.1df | 37 |
3 files changed, 104 insertions, 0 deletions
diff --git a/README.markdown b/README.markdown index 984c6378..39bc3666 100644 --- a/README.markdown +++ b/README.markdown @@ -489,6 +489,8 @@ Installed by the `install-bin` target: * `sue(8df)` execs `sudoedit(8)` as the owner of all the file arguments given, perhaps in cases where you may not necessarily have `root` `sudo(8)` privileges. +* `swr(1df)` allows you to run commands locally specifying remote files in + `scp(1)`'s HOST:PATH format. * `td(1df)` manages a to-do file for you with `$EDITOR` and `git(1)`; I used to use Taskwarrior, but found it too complex and buggy. * `try(1df)` repeats a command up to a given number of times until it diff --git a/bin/swr b/bin/swr new file mode 100755 index 00000000..56ab5919 --- /dev/null +++ b/bin/swr @@ -0,0 +1,65 @@ +#!/bin/sh +# Transparently wrap scp(1) targets on the command line +self=swr + +# 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 + +# Set a flag to manage resetting the positional parameters at the start of the +# loop +n=1 +for arg ; do + + # If this is our first iteration, reset the shell parameters + case $n in + 1) set -- ;; + esac + + # Test whether this argument looks like a remote file + if ( + + # Test it contains a colon + case $arg in + *:*) ;; + *) exit 1 ;; + esac + + # Test the part before the first colon has at least one character and + # only hostname characters + case ${arg%%:*} in + '') exit 1 ;; + *[!a-zA-Z0-9-.]*) exit 1 ;; + esac + + ) ; then + + # Looks like a remote file request; try to copy it into the temporary + # directory, bail out completely if we can't + dst=$td/$n + scp -q -- "$arg" "$dst" || exit + set -- "$@" "$dst" + + else + # Just a plain old argument; stack it up + set -- "$@" "$arg" + fi + + # Bump n + n=$((n+1)) +done + +# Run the command with the processed arguments +exec "$@" diff --git a/man/man1/swr.1df b/man/man1/swr.1df new file mode 100644 index 00000000..8792b0ed --- /dev/null +++ b/man/man1/swr.1df @@ -0,0 +1,37 @@ +.TH SWR 1df "January 2017" "Manual page for swr" +.SH NAME +.B swr +\- run a command including remote file arguments for scp(1) retrieval +.SH SYNOPSIS +.B swr +cat remote:.ssh/authorized_keys +.br +.B swr +diff .shrc remote:.shrc +.SH DESCRIPTION +.B swr +runs the command given in its arguments, first replacing any arguments in the +form HOST:PATH with copies of the specified files as retrieved with scp(1), +copied into a temporary directory that should be removed on exit under most +circumstances. +.P +This even works for the first argument (i.e. the command), provided that it +will run on the local system once copied in. +.SH CAVEATS +This only works for simple commands; you can't put shell syntax into any of the +arguments. +.P +The whole script will stop if even one of its arguments can't be copied in, as +there's no way to tell whether it's safe to proceed without some of the data. +.P +Don't even think about using this for mission-critical cases or situations +requiring high security. It's a convenience wrapper. +.P +You may not need this at all if your shell has working command substitution and +you find its syntax clearer: +.P + diff .shrc <(ssh remote 'cat .shrc') +.SH SEE ALSO +scp(1), mktd(1df) +.SH AUTHOR +Tom Ryder <tom@sanctum.geek.nz> |