如何区分 vim 终端和 bash 中的常规终端?

如何区分 vim 终端和 bash 中的常规终端?

vim 的最新版本引入了该:terminal命令,它在新的编辑器窗格中启动终端。

有没有办法识别从 vim 启动的这些 shell 与由 xterm/urxvt/gnome-terminal 启动的常规 shell?

答案1

自从Vim 补丁 8.1.049,Vim 确实导出VIM_TERMINAL了值为 的环境变量v:version。在此之前,您只能通过获取进程树信息来解决这个问题,或者可能但不是万无一失的通过测试$VIM$VIMRUNTIME环境变量来解决这个问题。

答案2

一般方法ps

您需要调查 shell 的父进程是否是vim。这在我的 Debian 9 中有效:

pid=1234                              # specify PID of the shell in question
ps -o comm= "$(ps -o ppid= "$pid")"

其中ps -o ppid= "$pid"返回父进程 ID。请注意,如果没有 PID 为 的进程$pid,则整个命令将变为ps -o comm= ""无效并抛出错误。

这假设您知道正确的 PID。例如,您可以迭代输出pidof bash

for pid in $(pidof bash); do ps -o comm= "$(ps -o ppid= "$pid")" 2>/dev/null; done

从外壳内部

在外壳内本身正确的PID是$$,因此上述简化为

ps -o comm= "$(ps -o ppid= "$$")"   # non-optimal though, see below

但也有$PPID。它在 shell 初始化期间由 shell 设置为其父进程 ID 的值。因此这应该几乎等同于:

ps -o comm= "$PPID"

几乎,因为一般来说,如果父进程死亡而 shell 存活(这是可能的),那么孤立的 shell 会得到一个新的父进程。我认为这会反映在ps -o ppid= "$$"而不是echo "$PPID"。在你的情况下,差异不应该有影响,因为:

  1. 如果 shell 存活下来,尽管两种方法会产生不同的结果,但结果都不会是这样的vim,所以最终的结论无论如何都是“不是 vim 终端”。
  2. 我希望vim在它退出时杀死启动的shell :terminal(但我目前无法确认这一点),因此上述观点无关紧要。
  3. 我希望任何交互式 shell 在失去控制终端时都会自行退出;因此,即使之前的预期是错误的,或者只是vim被强制终止(因此它无法向其子进程发送信号),shell 仍然会退出。因此,以上几点无关紧要。

因此,我认为可以安全地假设$PPID在实践中采用和不采用的方法是等效的。


注意,根据您的设置和启动方式vimps -o comm= ...可能不会返回文字vim字符串。例如,它可能是vim.basicvim.gtk3或其他内容。

相关内容