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

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

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

$EDITOR ~/newfile.txt

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

echo "Header" > ~/newfile.txt
$EDITOR ~/newfile.txt

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

答案1

如果您想在编辑器中预填充内容,请将此初始内容写入文件,就像您想象的那样。

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

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

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

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

或者,检查文件是否已被修改。执行此操作的可移植方法是保留初始内容的副本并调用cmp.如果类似sha256sum或 之类的命令sha可用,您可以使用这些命令并比较前后的哈希值。如果文件的时间戳已更改,您可能仍希望认为该文件已被编辑 - 也许用户确实想提交默认输入。

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

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

"$EDITOR" +"$line" "$file"

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

相关内容