在创建新 window/pane 时阻止 Tmux 取消引用路径

Stop Tmux from dereferencing path when creating new window/pane

当我在 tmux 中创建新的 window/pane 时,例如通过 tmux neww 或键绑定 prefix+cprefix+% 等,新窗格的工作目录与以前的相同窗格,但路径中有取消引用的符号链接。

例如,如果我在

/home/user/my-link/a

my-link -> /mnt/user/,我到了

/mnt/user/a

将新目录显式传递给 tmux 也不起作用:

tmux neww -c $(pwd)

我可以禁用这种解除引用吗?我想我可以通过 tmux 环境变量编写解决方法,但我想要一个更清晰的解决方案。

我是 运行 tmux 1.8 来自 Ubuntu 14.04 的回购。

此行为无法禁用,似乎甚至无法在 tmux 中实现此功能 (source)。

在 Linux 中,进程的工作目录始终作为实际目录进行跟踪(已解析符号链接)。你可以通过在目录/home/user/my-link/a中发出ls -l /proc/self/cwd来查看,它会显示当前工作目录实际上是/mnt/user/a。这样做的原因可能是当进程在该目录中时删除(或什至更改)符号链接时不会 运行 遇到麻烦。

您的 shell 将 /home/user/my-link/a 显示为工作目录的功能完全在 shell 本身中实现。它在 pwd 环境变量中跟踪它,但 tmux 无法访问子进程的环境变量。

我发现创建新 window 的最简单方法是

tmux neww "cd $(pwd); exec $SHELL"

除了 Philipp 的回答之外,还有一种方法可以解决运行时替换问题。您只需要注意,每次更改目录时,全局 tmux 变量 PWD 都会更新为 $PWD。 在你的 .bashrc:

mycd() {
  \cd "$@"
  [ -n "$TMUX" ] && tmux set-environment -g PWD $PWD
}
alias cd=mycd

在你的.tmux.conf:

bind-key C-n new-window

总结 Philipp Wendler 和 Yacc 的所有回答和评论,我想出了一个非常适合我的解决方案。我应该提到它在我的机器上使用了一些技巧,所以应该小心使用它们。

事实证明tmux不能自己解决问题,我们需要一些技巧。

首先,让每个窗格在 tmux 变量 TMUX_<pane-id>_PATH 中描述它的路径。这可以通过别名 cd 或提示代码(我正在使用它)来完成,没关系:

# get $pane set to pane id without %
tmux set-environment TMUX_"$pane"_PATH $(pwd)

其次,路径脚本中有tmux-neww.sh。它将 NEWW 变量设置为当前真实路径的方式。它获取当前窗格 ID 作为参数:

#!/bin/bash
pane=$(echo "" | tr -d '%')
pane_path=$(tmux show-environment TMUX_"$pane"_PATH | sed 's/^[^=]*=//g')
tmux set-environment NEWW "$pane_path"
tmux neww

第三,在tmux.conf

bind C \
    run "tmux-neww.sh #{pane_id}"

第四,我在bash.bashrc中进行了测试,如果shell在tmux中被运行。如果是这样,它会进行一些更改(即添加一些变量,我的重提示会将一些数据发送到 tmux 变量)。此处测试是否设置了 NEWW:

neww=$(tmux show-environment NEWW 2> /dev/null | sed 's/^[^=]*=//')
if [ "$neww" != "-NEWW" ] && [ "$neww" != "" ] ; then
    cd "$neww"
fi
tmux set-environment -r NEWW

这可能会让人不知所措,但效果还不错。

鱼 shell 用户。

实现来自@yacc 的想法 + @lapshin-dmitry 的评论。

第一步

更新 fish_prompt.fish 以便更新 TmuxPWD 变量

# ~/.config/fish/functions/fish_prompt.fish

function update_tmux_pwd
    if test -n "$TMUX"
        tmux set-environment -g PWD $PWD
    end
end

function fish_prompt --description 'Write out the prompt'
   # ... original body of the function
   update_tmux_pwd
end

第 2 步

检查 fish shell 是否真的更新了 Tmux 变量 PWD:

~> tmux show-environment -g PWD
PWD=/home/username
~> cd some_directory
some_directory> tmux show-environment -g PWD
PWD=some_directory

第三步

重新绑定在 .tmux.conf 中创建新窗格或 window 的键:

# ~/.tmux.conf

bind '"' split-window -c "#{PWD}"
bind % split-window -h -c "#{PWD}"
bind c new-window -c "#{PWD}"

正在指定目录中启动 tmux 会话

为了完整起见,如何修改 tmux 别名,在指定目录中启动 tmux 会话,以便不取消引用符号链接,应用来自

的原始想法
# ~/.config/fish/alias.fish

alias tts 'tmux attach -t sandbox || tmux new -s sandbox "cd /home/username/git/sandbox; exec $SHELL"'