#!/bin/sh set -eu usage() { cat <<-'EOF' Usage: grun [-r RECIPIENT] FILENAME -- COMMAND... grun -h EOF } help() { cat <<-'EOF' Options: -r RECIPIENT the recipient to encrypt to. Can be provided multiple times for multiple recipients. -h, --help show this message COMMAND A command to be executed, that accepts input in STDIN and emits result in STDOUT, and emits errors as non-zero return codes. FILENAME The GPG-encrypted file to be processed. If it doesn't exist yet, it will be created. Edit the encripted FILENAME in a pipeline, using COMMAND to modify the content. If COMMAND emits a non-zero return code, the file is left unmodified. Examples: Edit "secrets.txt.gpg" using `vipe` and the default recipient: $ grun secrets.txt.gpg -- vipe Delete lines containing "TODO" in todos.gpg for specific keys: $ grun -r ABC123DEF321 todos.gpg -- sed '/TODO/d' EOF } for flag in "$@"; do case "$flag" in (--) break ;; (--help) usage help exit ;; (*) ;; esac done while getopts 'rh' flag; do case "$flag" in (r) RECIPIENTS_FLAG="${RECIPIENTS_FLAG:-} -r $OPTARG" ;; (h) usage help exit ;; (*) usage >&2 exit 2 ;; esac done shift $((OPTIND - 1)) FILENAME="${1:-}" eval "$(assert-arg -- "$FILENAME" 'FILENAME')" shift if [ "${1:-}" != '--' ]; then printf 'Missing "--" separator\n\n' >&2 usage >&2 exit 2 fi shift eval "$(assert-arg -- "${1:-}" 'COMMAND')" if [ ! -e "$FILENAME" ]; then OUT="$(printf '' | "$@")" else OUT="$(gpg -dq "$FILENAME" | "$@")" fi # GPG recipients can't contain spaces: # shellcheck disable=2086 printf '%s\n' "$OUT" | gpg -e ${RECIPIENTS_FLAG:--r eu@euandre.org} | sponge "$FILENAME"