首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用GUI和CLI文本编辑器#3在Linux (作为root用户)中编辑系统文件

使用GUI和CLI文本编辑器#3在Linux (作为root用户)中编辑系统文件
EN

Code Review用户
提问于 2021-09-21 10:40:05
回答 1查看 80关注 0票数 1

一年半前,我在这里发布了这个脚本的第二次迭代,以便进行回顾:

使用GUI和CLI文本编辑器#2在Linux (作为root)中编辑系统文件

从那时起,它已经“冬眠”,因为我有太多的工作,我想请您审查可能的最终编辑。我做了很大的努力,使它成为最终的,但我们都知道,总是有一些改进的空间。提前谢谢你!

如该文件所述:

我的意图是编写一个通用函数,用于通过sudoedit运行用于不同目的的各种文本编辑器,即将文件作为根安全地编辑。例如,如果在文件编辑过程中出现了电源丢失,则另一个示例可能会丢失SSH连接,等等。

脚本遵循

代码语言:javascript
复制
#!/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
EN

回答 1

Code Review用户

回答已采纳

发布于 2021-09-27 21:23:02

除了你的自我回顾,我注意到一些我认为可能值得指出的(很小的)事情。

首先是设计意见,而不是对代码的评论。我不确定将编辑器列表放在文件中的变量中是最好的方法--它有其优点,但允许在配置文件中单独管理编辑器可能有好处。如果我是这个脚本的用户,我宁愿被告知去编辑类似于$XDG_CONFIG_DIRS/sudoedit-enhanced文件的内容,而不是被鼓励编辑脚本本身。

sudoedit_run打印sunano作为用法示例有点奇怪,不管是想要还是可用。提供一个成功定义的别名会不会是现实的呢?

虽然您通常可以假设/tmp存在,但用户可能更喜欢将他们的临时文件存储在其他地方。考虑让mktemp调用使用--tmpdir标志来创建一个相对于用户设置的$TMPDIR的文件--不是很多用户会关心,但是那些关心它的用户可能会有很强烈的感觉。

别名生成器在其名称包含空格的编辑器上表现得有点奇怪--即使它们很少这样做,二进制文件也可以这样做。现在,当您将每个编辑器作为一个单词存储在一个空格分隔的字符串中时,您真的不需要担心如何处理它们,但是如果有一天,您最终会以这样一种方式重构某个东西,使您能够做一些像cli_editor="per se"这样古怪的事情,那么请考虑一下像su$cli_editor="sudoedit_run cli $cli_editor"这样的行会如何对此做出反应(有时这是一个错误,但并不总是一个错误,并且可能有副作用)。引用别名,以强制因别名无效而导致失败(至少在bash中,不确定其他shell是否允许别名中的空格)可能更好。

sudoedit_run在如何检查编辑器方面也有一个微妙的错误-- command -v将报告shell内置程序的名称,以支持命令。如果有人做了一些愚蠢的事情,比如将echo作为编辑器列出,command -v echo将返回echo。只要当前目录中有一个名为echo的文件,就会导致它正常工作,但是如果没有正确安装,就会报告它没有正确安装。这件案子已经够多了,几乎可以肯定不值得关心,但仍然

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/268213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档