If I'm using gnome-terminal in a working directory whose path includes symlinks and I open a new tab, the symlinks will be expanded to their destinations in the working directory of the new tab.

Is there any way to preserve the symlinks when opening a new tab?

  • I cannot reproduce the behavior you describe with Ubuntu 10.04 and all default settings for gnome-terminal and bash. The problem may be a setting in your .bashrc; try moving it temporarily out of the way to check. If the problem persists, add more information, at least the versions of gnome-terminal and bash, and a detailed list of steps to reproduce this behavior. – Gilles Aug 31 '10 at 21:15
  • 1
    I can reproduce it. By "directory that includes symlinks" he means "working directory whose path includes symlinks". Under gnome-terminal 2.30.2 and bash 4.1.5: mkdir -p foo/bar/baz; ln -s foo/bar/baz link; cd link -- then create new tab -- then pwd. It will report "foo/bar/baz" rather than "link". – Jander Dec 5 '10 at 21:30
  • @Jander, thanks, I'll edit to include your clarification. – Ian Mackinnon Dec 5 '10 at 22:30

I suspect there is no truly good answer to this. gnome-terminal finds bash's current working directory by inspecting /proc/<pid>/cwd, which has the symlinks expanded (probably for security reasons, if nothing else). I don't know of another way for one process to find another process's working directory.

As a workaround, there are some bash tricks you could try, but see the WARNING below! In .bashrc:

PROMPT_COMMAND='pwd >~/.bashlocal_saved_dir'

[ -n "$PS1" -a -f ~/.bashlocal_saved_dir ] && cd `cat ~/.bashlocal_saved_dir`
# end of .bashrc

This will do two things. First, every time bash displays the prompt, it will first write its current working directory into the file .bashlocal_saved_dir in your home directory. Second, when bash starts interactively (as opposed to running a script), it will change to the directory stored in that same file. This means that when you start a new interactive bash, it will start in the same dir as the bash that last displayed its prompt. Note that you can hit Enter to cause a bash to redisplay its prompt, thus making it the last. :)

WARNING: This is a hack, and I have only tried it up to the point that I know it works. Think bubble gum and shoestrings. It may have surprising effects, and will certainly not work as cleanly as gnome-terminal's approach. In particular, if you're running a lot of tabs at once, all doing background tasks, you may very well end up in the "wrong" directory when opening a new tab.

  • 1
    +1. But I think a safer solution, if one only has a few working dirs with symlinks, is check if you're in one of them, and call cd accordingly. – ShreevatsaR Nov 11 '11 at 7:02

This bug is being tracked on Ubuntu Launchpad and GNOME Bugzilla.

Since this mainly annoys me with only a few directories, I use the following simpler workaround.

Suppose you have /home/username/work as a symlink to /long/path/named/asdf. So you do cd ~/work in gnome-terminal, open a new tab, and find terminal reporting the full path. To fix this, just put the following in your .bashrc:

cd ${PWD/\/long\/path\/named\/asdf/$HOME\/work}

When gnome-terminal starts a new shell, it gets the current directory with $PWD, and if it contains /long/path/named/asdf, it replaces that string with $HOME/work, and cds to the resulting string. If $PWD does not contain the string, it is equivalent to cd $PWD, which does nothing.


I love @ShreevatsaR's answer. Expanding it to signal when this is happening and to make it so I can undo with a quick popd, I'm using:

for sub in \
    "${PWD/\/home\/vus\/.cache\/vus\/build/\/vrepos\/build}" \
  if [ "$sub" != "${PWD}" ] ; then
     echo -n "pushd "
     pushd "$sub"
     break # prevents first pushd from tripping later checks

An example new window (with PS1='#prompt# \[\033[01;34m\]\w\[\033[00;35m\]$(__git_ps1)\[\033[00m\]\$ '), including use of popd shows:

pushd /vrepos/build/2_dev_Ubuntu_Debug /home/vus/.cache/vus/build/2_dev_Ubuntu_Debug
#prompt# /vrepos/build/2_dev_Ubuntu_Debug$ popd
#prompt# /home/vus/.cache/vus/build/2_dev_Ubuntu_Debug$ 

Found this issue to be unresolved as of gnome-shell 3.14.4.

A workaround would be to use the bash Shell Variable SHLVL (which is incremented by 1 every time bash is started) in .bashrc, as follows

# bash login shell would be at level 1.
[[ $SHLVL -eq 2 ]] && cd

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.