命令行程序延迟到默认文本编辑器

Command line program defer to default text editor

我有一个工作流程,我希望用户能够为其编辑一些 "free-form" 文本。如果这是在网络表单上,想象这是一个 <textarea>。想象一下,例如您正在填写用户个人资料。对于 "name" 等字段,用户使用 ENTER 键继续的简单提示非常好。但对于 "bio" 字段之类的内容,我们需要捕获换行符。

一般怎么做?

(理想情况下,我的工具将在 bash、Python、Ruby 或 Java 中,但让工作流程友好比工具更重要用于创建它。另外,我恰好在Ubuntu环境中。)

更新: 上下文是我将通过此工作流程通过 SSH 和 运行 登录系统。出于这个原因,我需要坚持使用 shell 友好的工具。我很乐意使用任何必要的工具来完成工作。我不是在征求意见。我只是不知道在执行 prompt/response 风格的命令行应用程序的过程中使用 vim 之类的正确术语或技术。

处理此问题的常用方法确实是代表他们启动用户最喜欢的(命令行)文本编辑器,等待他们完成编辑,然后使用用户输入继续您自己的业务。用于 git commit 的过程是一个非常著名的例子。

您的程序必须执行以下步骤。

  • 创建一个临时文件。您可以使用 mktemp 程序从 shell 脚本执行此操作。

    考虑放置一个 trap 来删除文件,如果您的脚本在此过程中被杀死,这样您就不会乱扔用户的文件系统。 (由于 mktemp 会默认在 /tmp/ 中创建文件,并且通常会定期清除该目录中的所有内容,所以这还算不错。)

  • 如果您不希望用户从一个空文件开始,而是为他们提供一个模板作为开始,请立即将任何此类文本写入文件。

  • 启动用户最喜欢的编辑器打开该文件。您的脚本将阻塞,直到用户关闭编辑器。

    有趣的问题当然是如何决定启动什么程序。普遍认可的技术是按顺序尝试以下选项。

    • 环境变量 PACKAGE_EDITOR 中列出的任何命令,您可以在其中用您的应用程序名称替换 PACKAGE
    • 环境变量中列出的任何命令EDITOR
    • vi
    • 这样的标准编辑器
    • 出错

    通过在通用 EDITOR 变量之前尝试特定于您的应用程序的环境变量,用户可以对那些他们需要与默认编辑器不同的编辑器的应用程序进行特殊处理。

    因为 chrylis has pointed out in the comments, you may also check an environment variable named VISUAL that (according to this thread) 曾经被用来提供一种在视频终端上使用更高级的编辑器的方法,该编辑器能够 运行 它。

  • 读回文件内容。考虑为用户提供在编辑期间中止该过程的选项。 Git,例如,将保存空文件解释为请求堕胎。

  • 删除临时文件。

不要忘记为您的用户正确记录环境变量的影响。

这是一个您可以玩的简单示例。

#! /bin/bash -eu

edit=
tempfile=

if [ "${EXAMPLE_EDITOR:+set}" = set ]
then
    edit="${EXAMPLE_EDITOR}"
elif [ "${EDITOR:+set}" = set ]
then
    edit="${EDITOR}"
else
    edit='vi'
fi

function cleanup {
    [ -z "${tempfile}" ] || rm -f "${tempfile}"
}

trap cleanup EXIT

tempfile="$(mktemp)"

cat <<EOF > "${tempfile}"
# Please edit this file to contain your list of noble wishes, then
# save and exit the editor.  If you decide to abort the process,
# delete everything and save an empty file.
EOF

${edit} "${tempfile}" || {
    echo "Editing command '${edit} ${tempfile}' is not working or" \
         "was aborted on purpose" >&2
    exit 1
}

if [ ! -s "${tempfile}" ]
then
    echo "Aborting due to empty wish list" >&2
    exit 1
fi

# Do something with the list of noble wishes...

请注意,我没有引用 ${edit} 的扩展,因此 EDITOR='emacs -nw' 之类的内容也是可能的。