是否可以找到哪个 vim/tmux 打开了我的文件?

是否可以找到哪个 vim/tmux 打开了我的文件?

tmux在工作中使用它作为我的 IDE。我还在vim各种 tmux 窗格中运行,并且经常将进程置于后台(或者我只是关闭窗口 - 我将 vim 配置为在窗口关闭时不删除打开的缓冲区)。现在我遇到了一个问题,因为我想要编辑的文件在我的其他 vim 会话之一中打开,但我不知道是哪一个。

是否可以在不手动检查所有窗口和窗格的情况下找到哪一个?在我的特殊情况下,我知道我没有编辑它,vim ~/myfile.txt因为ps aux | grep myfile.txt没有返回任何内容。

答案1

它没有告诉我一切,但我使用fuser ~/.myfile.txt.swp它给了我 vim 会话的 PID。运行后ps aux | grep <PID>我能够找出我正在使用哪个 vim 会话,这给了我一个提示,告诉我在哪个窗口中打开了它。

感谢 Giles 的灵感以及一点坚持和运气,我想出了以下命令:

⚘ (FNAME="/tmp/.fnord.txt.swp"; tmux switch -t $(tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_tty}' | grep $(ps -o tty= -p $(lsof -t $FNAME))$ | awk '{ print $1 }'))

解释一下它的作用:

(FNAME="/tmp/.fnord.txt.swp";

这将创建一个子 shell 并设置FNAME为环境变量。严格来说,这不是必需的 - 您可以$FNAME自己替换为文件名,但它确实使编辑变得更容易。现在,从内到外进行工作:

lsof -t $FNAME

这会产生仅有的打开文件的进程的 PID。

ps -o tty= -p $(...)

这会产生pts我们使用 发现的 PID 的lsof

tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_tty}'

这会生成一个条目窗格列表,例如session:0.1 /dev/pts/1。第一部分是 tmux 喜欢的目标格式,第二部分是pts

| grep $(...)$

这会过滤我们的窗格列表 - 尾随$的是,因此它只会匹配我们关心。我很偶然地发现了 和pts/2pts/22所以有匹配,哎呀!

| awk '{ print $1 }'

这会生成session:0.1适合传递到 的窗格输出部分tmux switch -t

这应该适用于会话和窗格,使包含交换文件的窗格成为焦点。

答案2

你的问题的概要答案是:

for all the tmux sessions:
  for all the windows in the session:
      for all the panes in windows:
         for all sub process pids (recursively):
            find the open files

所有会话: tmux list-sessions -F '#{session_id}:#{session_name}

所有窗口: tmux list-windows -F '#{window_id}XX#{window_index}XX#{window_name}' -t "$session_id"

所有窗格: tmux list-panes -F '#{pane_id}:#{pane_index}:#{pane_pid}' -t ""$session_id":"$window_index""

所有子进程 pid: ps -o pid --no-headers --ppid $pid

打开文件:lsof -p $pid

上述的实现显示了一个树:

sessions
   windows
      panes
         process
            open files

显示哪个进程打开了文件(在我的例子中也是 vim)。

在此输入图像描述

可以在以下位置找到https://github.com/nkh/tmux-ls

它已经在 github 上存在 5 年了,但我鼓励你克隆它,以防它被删除(或 github 崩溃)

相关内容