'Stop Tmux from dereferencing path when creating new window/pane
When I create new window/pane in tmux, for example via tmux neww or keybindings prefix+c, prefix+% etc, the new pane gets working directory the same as previous pane, but with dereferenced symbolic links in path.
For example, if I am at
/home/user/my-link/a
where my-link -> /mnt/user/, i got to
/mnt/user/a
Explicitly passing new directory to tmux does not work either:
tmux neww -c $(pwd)
Can I disable such dereferencing? I think I can write a workaround via tmux environment variables, but I want a clearer solution.
I am running tmux 1.8 from repos on Ubuntu 14.04.
Solution 1:[1]
Summaring all answers and comments from Philipp Wendler and Yacc, I came up with solution that works perfectly for me. I should mension that it uses some tricks on my machine, so they should be used carefully.
It was shown that tmux can't solve problem on it's own, we need some tricks.
First, make that every pane describe it's path in tmux variable TMUX_<pane-id>_PATH. That could be done via aliasing cd or prompt code (I am using that), it doesn't matter:
# get $pane set to pane id without %
tmux set-environment TMUX_"$pane"_PATH $(pwd)
Second, have in path script tmux-neww.sh. It sets NEWW variable to current real path's way. It gets current pane-id as a param:
#!/bin/bash
pane=$(echo "$1" | tr -d '%')
pane_path=$(tmux show-environment TMUX_"$pane"_PATH | sed 's/^[^=]*=//g')
tmux set-environment NEWW "$pane_path"
tmux neww
Third, in tmux.conf:
bind C \
run "tmux-neww.sh #{pane_id}"
Forth, I have in bash.bashrc test, if shell is being run in tmux. If so, it makes some changes (i.e. adds some variables that my heavy prompt will send some data to tmux variables). Here it tests, if NEWW is set:
neww=$(tmux show-environment NEWW 2> /dev/null | sed 's/^[^=]*=//')
if [ "$neww" != "-NEWW" ] && [ "$neww" != "" ] ; then
cd "$neww"
fi
tmux set-environment -r NEWW
That may be overwhelming, but works OK.
Solution 2:[2]
This behavior cannot be disabled, and it seems it is not even possible to implement this feature in tmux (source).
In Linux the working directory of a process is always tracked as the actual directory (with symlinks resolved). You can see this by issuing ls -l /proc/self/cwd in the directory /home/user/my-link/a, it will show that the current working directory is actually /mnt/user/a. The reason for this is probably for not running into trouble when the symlink is deleted (or even changed) while a process is in that directory.
The feature that your shell shows you /home/user/my-link/a as working directory is implemented completely in the shell itself. It keeps track of it in the pwd environment variable, but tmux cannot access environment variables of subprocesses.
The easiest way I have found to create a new window as you would like to is
tmux neww "cd $(pwd); exec $SHELL"
Solution 3:[3]
In addition to Philipp's answer, there's a way to work around the runtime substitution problem. You just need to take care that every time you change the directory the global tmux variable PWD is updated with $PWD. In your .bashrc:
mycd() {
\cd "$@"
[ -n "$TMUX" ] && tmux set-environment -g PWD $PWD
}
alias cd=mycd
In your .tmux.conf:
bind-key C-n new-window
Solution 4:[4]
For fish shell users.
Implementing the idea from the answer above by @yacc + comment by @lapshin-dmitry.
Step1
Update fish_prompt.fish so that it updates PWD variable in Tmux
# ~/.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
Step 2
Check if fish shell actually updates Tmux variable PWD:
~> tmux show-environment -g PWD
PWD=/home/username
~> cd some_directory
some_directory> tmux show-environment -g PWD
PWD=some_directory
Step3
rebind keys that create new pane or window in .tmux.conf:
# ~/.tmux.conf
bind '"' split-window -c "#{PWD}"
bind % split-window -h -c "#{PWD}"
bind c new-window -c "#{PWD}"
Starting tmux session in a specified directory
For the sake of completeness, how to modify a tmux alias, which starts tmux session in a specified directory, so that symlinks are not dereferenced, applying the original idea from yet another answer above
# ~/.config/fish/alias.fish
alias tts 'tmux attach -t sandbox || tmux new -s sandbox "cd /home/username/git/sandbox; exec $SHELL"'
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Philipp Wendler |
| Solution 3 | yacc |
| Solution 4 |
