从带有文本的 shell 脚本启动编辑器

Sau*_*ode 3 editors shell-script

我知道可以从 shell 脚本启动默认编辑器。例如,假设$EDITOR设置了环境变量:

$EDITOR ~/newfile.txt
Run Code Online (Sandbox Code Playgroud)

是否可以使用预先填充的文本打开新文件?我能想到的一种方法是在打开文件之前创建文件:

echo "Header" > ~/newfile.txt
$EDITOR ~/newfile.txt
Run Code Online (Sandbox Code Playgroud)

但是如果文本编辑器打开的文件是预先填充的,但也可以被丢弃,那就更好了。这可能吗?

Gil*_*il' 5

如果您想在编辑器中预填充内容,请按照您的想法将此初始内容写入文件。

没有办法“将编辑器置于打开它后输入几行的状态”,它适用于不同的编辑器。在许多编辑器中,这意味着文件将未保存,但没有统一的方法来实现该状态,并且有些编辑器根本没有这个概念(例如Scratch)。

但是,您可以检测文件是否完全从编辑器中保存。如果文件未保存,则放弃操作。要检测文件是否已保存,请检查其前后修改时间。

file=$(mktemp)
cat <<EOF >"$file"
Hello
world
EOF
old_metadata=$(ls -li "$file")
"${VISUAL:-"${EDITOR:-vi}"}" "$file"
new_metadata=$(ls -li "$file")
if [ "$new_metadata" = "$old_metadata" ]; then
  … # unchanged file, abandon operation
else
  … # modified file, carry on
fi
Run Code Online (Sandbox Code Playgroud)

请注意,如果文件被修改但大小和inode 没有改变并且修改时间不到1 秒,则该脚本将认为该文件没有被修改。如果是人工编辑,则不会发生这种情况,但如果$EDITOR是自动提交修改后的文件的脚本,则很容易发生。以便携的方式很难做得更好。使用 GNU coreutils,如果文件系统支持具有足够精度的亚秒时间戳,则传递--full-time选项以ls解决此问题。

或者,检查文件是否已被修改。这样做的可移植方式是保留初始内容的副本并调用cmp. 如果命令喜欢sha256sumsha可用,您可以使用这些命令并比较前后的哈希值。如果文件的时间戳已更改,您可能仍要考虑该文件已被编辑——也许用户确实想要提交默认输入。

这种技术是几个版本控制系统在启动编辑器来编辑提交消息时使用的技术。如果用户不保存文件,则提交将中止。

如果您还想将光标放在输入的末尾,则没有通用的方法可以做到这一点。有很多编辑器,你可以写

"$EDITOR" +"$line" "$file"
Run Code Online (Sandbox Code Playgroud)

编辑器将打开,光标位于指定行。许多编辑器都支持这一点,包括 vi(所有变体)、emacs、joe 和 gedit,但 kwrite 不支持。