#! /usr/bin/bash set -euo pipefail IFS=$'\n\t' default_editor() { if [ -n "${SUDO_EDITOR+set}" ]; then echo "${SUDO_EDITOR}" elif [ -n "${VISUAL+set}" ]; then echo "${VISUAL}" elif [ -n "${EDITOR+set}" ]; then echo "${EDITOR}" else echo "No editor configured" 1>&2 exit 1 fi } try_command() { if "$@" 2> /dev/null; then return elif run0 "$@" > /dev/null; then return else exit 2 fi } make_editable_copy() { orig_file="$1" tempfile="$2" try_command cp "${orig_file}" "${tempfile}" } elevate_permissions() { tempfile="$1" orig_file="$2" try_command chown --reference "${orig_file}" "${tempfile}" try_command chmod --reference "${orig_file}" "${tempfile}" } update_file() { tempfile="$1" orig_file="$2" try_command mv --force "${tempfile}" "${orig_file}" } clean_tempfiles() { tempfile="$1" rm --force "${tempfile}" "${tempfile}.orig" } if [ "$#" -ne "1" ]; then echo "Expected exactly one input file. Usage:" 1>&2 echo " $0 FILE" 1>&2 exit 1 fi editor_cmd="$(default_editor)" echo "Editing using the command \"${editor_cmd}\"" IFS=' ' read -r -a editor <<< "${editor_cmd}" orig_file="$1" tempfile="$(mktemp)" echo "Using temporary file ${tempfile}" make_editable_copy "${orig_file}" "${tempfile}" cp "${tempfile}" "${tempfile}.orig" "${editor[@]}" "${tempfile}" if cmp --quiet "${tempfile}" "${tempfile}.orig"; then echo "No change to file" else elevate_permissions "${tempfile}" "${orig_file}" update_file "${tempfile}" "${orig_file}" fi clean_tempfiles "${tempfile}"