One year and a half ago I posted the second iteration of this script for a review here:
Editing system files in Linux (as root) with GUI and CLI text editors #2
Since then, it has been "hibernated" as I had way too much work, and I would like to ask you for a review of the possible final edit. I made a big effort for it to be final, but we all know there is always some space to improve. Thank you in advance!
As stated in there:
My intention is to POSIX-ly write one generalized function for running various text editors I use for different purposes through
sudoedit
, i.e. editing files as root safely. Safely = for instance, if a power loss occurs during the file edit; another example could be lost SSH connection, etc.
The script follows
#!/bin/sh
# Please, customize these lists to your preference before using this script!
cli_editors='vi nano'
gui_editors='subl xed'
# NON-COMPLIANT: code -w --user-data-dir; I did not find a way to run it through `sudoedit`;
# atom -w --no-sandbox; gedit -w does not work via rooted ssh; pluma does not have -w switch
# USAGE INSTRUCTIONS
# 1. Customize the editor lists at the beginning of this script.
#
# 2. Bash: Source this script in your ~/.bashrc or ~/.bash_aliases with:
# . /full/path/to/sudoedit-enhanced
# Other shells: Generally put it inside your shell's startup config file...
#
# 3. Call an alias, for instance, one CLI, and one GUI editor:
# sunano /path/to/file
# susubl /path/to/file
#
# Explanation: This script works with standard `sudoedit`, but
# it does a bit more checks and allows some GUI editors to be used.
# It needs to be sourced into your shell's environment first.
# Then simply use the pre-defined aliases or define some yourself.
sudoedit_err ()
{
printf >&2 '%s\n' 'Error in sudoedit_run():'
printf >&2 '%b\n' "$@"
exit 1
}
sudoedit_run ()
{
# print usage
if [ "$#" -eq 2 ]; then
printf >&2 '%s\n' 'Usage example: sunano /file1/path /file2/path'
exit 1
fi
# sudo must be installed
if ! command -v sudo > /dev/null 2>&1; then
sudoedit_err "'sudo' is required by this function. This is because" \
"'sudoedit' is part of 'sudo'\`s edit feature (sudo -e)"
fi
# the first argument must be an editor type
case "$1" in
('cli'|'gui') ;;
(*) sudoedit_err "'$1' is unrecognized editor type, expected 'cli' or 'gui'." ;;
esac
# store editor's type and name and move these two out of argument array
editor_type=$1; editor_name=$2; shift 2
# find and store path to this editor
editor_path=$( command -v "$editor_name" 2> /dev/null )
# check if such editor = executable path exists
if ! [ -x "$editor_path" ]; then
sudoedit_err "The '$editor_name' editor is not properly installed on this system."
fi
# `sudoedit` does not work with symlinks!
# translating symlinks to normal file paths using `readlink` if available
if command -v readlink > /dev/null 2>&1; then
for file in "$@"; do
if [ -L "$file" ]; then
if ! file=$( readlink -f "$file" ); then
sudoedit_err "readlink -f $file failed."
fi
fi
set -- "$@" "$file"
shift
done
fi
if [ "$editor_type" = gui ]; then
# 1. GUI editors will "sit" on the terminal until closed thanks to the wait option
# 2. Various editors errors might flood the terminal, so we redirect all output,
# into prepared temporary file in order to filter possible "sudoedit: file unchanged" lines.
if tmpfile=$( mktemp /tmp/sudoedit_run.XXXXXXXXXX ); then
SUDO_EDITOR="$editor_path -w" sudoedit -- "$@" > "$tmpfile" 2>&1
grep 'sudoedit:' "$tmpfile"
rm "$tmpfile"
else
sudoedit_err "mktemp /tmp/sudoedit_run.XXXXXXXXXX failed."
fi
else
# 1. CLI editors do not cause problems mentioned above.
# 2. This is a generic and proper way using `sudoedit`;
# Running the editor with one-time SUDO_EDITOR setup.
SUDO_EDITOR="$editor_path" sudoedit -- "$@"
fi
}
sudoedit_sub ()
{
( sudoedit_run "$@" )
}
# Editor aliases generators:
# - avoid generating editors aliases for which editor is not installed
# - avoid generating editors aliases for which already have an alias
for cli_editor in $cli_editors; do
if command -v "$cli_editor" > /dev/null 2>&1; then
# shellcheck disable=SC2139,SC2086
if [ -z "$( alias su$cli_editor 2> /dev/null)" ]; then
alias su$cli_editor="sudoedit_sub cli $cli_editor"
fi
fi
done
for gui_editor in $gui_editors; do
if command -v "$gui_editor" > /dev/null 2>&1; then
# shellcheck disable=SC2139,SC2086
if [ -z "$( alias su$gui_editor 2> /dev/null)" ]; then
alias su$gui_editor="sudoedit_sub gui $gui_editor"
fi
fi
done
unset cli_editors gui_editors