Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm using a tiling window manager and I switched from gnome-terminal with multiple tabs to multiple urxvt instances managed by the window manager. One of the features I miss is the ability to open a new terminal that defaults to the working directory of the last one.

In short: I need a way to open a new urxvt (bash) that defaults to $PWD of the last used one.

The only solution that comes to my mind is to save the current path on every cd with something like this:

echo $PWD > ~/.last_dir

and restore the path on the new terminal in this way:

cd `cat ~/.last_dir`

I can source the second command in .bashrc but I don't know how to execute the first one on every directory change :)

Any simpler solution that does not involve screen or tmux usage is welcome.

share|improve this question
Are you using the "tabbed" perl extension of urxvt? – rozcietrzewiacz Feb 23 '12 at 18:32
No tabs, I'm using new terminals managed by WM – Luca Feb 23 '12 at 18:36
up vote 6 down vote accepted

I see three solutions using .last_dir. You can place the echo $PWD > ~/.last_dir either:

  1. In a special function that would be a wrapper for cd:

    function cd_
      [[ -d "$@" ]] || return 1
      echo "$@" > ~/.last_dir
      cd "$@"

    Place this in your .bashrc and then use cd_ instead of cd everytime you want your new working directory to be stored.

  2. In your $PROMPT_COMMAND (not recommended):

    PROMPT_COMMAND="$PROMPT_COMMAND; pwd > ~/.last_dir"

    You can test this directly from the terminal or place in .bashrc. This solution, however, triggers disk write each time the prompt appears, which might cause trouble - but on the other hand, .last_dir would contain the current directory no matter how you got there.

  3. In a custom perl extension script for rxvt. I've never created one myself, but you can find quite a few examples on the web.

share|improve this answer
PROMPT_COMMAND that's what I was looking for. I will try this solution hoping it doesn't affect performances. – Luca Feb 23 '12 at 19:25
Well, it is a rather crude way, frankly. Personally, I like Michael's solution best :) – rozcietrzewiacz Feb 23 '12 at 19:33
I like the perl extension way, if it needs to work outside of the terminal; it seems cleaner than hacking something into PROMPT_COMMAND, one of the most abused environment variables of all time – Michael Mrozek Feb 23 '12 at 19:37
It seems that $PWD is evaluated only the first time – Luca Feb 23 '12 at 21:25
@neon Aaah... Sorry. The problem is with with how the PROMPT_COMMAND is quoted. (Or rather, how $PWD was not quoted.) Let me fix this... There. That ought to do it. – rozcietrzewiacz Feb 23 '12 at 21:33

This is actually pretty trivial; if you run urxvt from within your existing urxvt window, the new window will be in the same directory. I have dup aliased to urxvt & for this reason. If you want it bound to a hotkey, you can use bash's bind command. For example, to bind it to F1:

$ bind '"\e[11~": "urxvt &\n"'
share|improve this answer
Thanks for the tip. I knew that terminal child processes maintained the state but I didn't know that you can bind a key to a command in bash. I'd like to do this from WM to avoid focusing the terminal. – Luca Feb 23 '12 at 19:12
I like that. No disk writes and the only execution takes place when you're about to open the new terminal. – rozcietrzewiacz Feb 23 '12 at 19:14
The only thing I'd change is to use ( urxvt & ) &>/dev/null instead of just backgrounding. – rozcietrzewiacz Feb 23 '12 at 19:17
This solution is great and more flexible but I don't like to use 2 bindings, one to launch the terminal and one to fork a new one. – Luca Feb 23 '12 at 19:46

I'm currently using this version of #1 solution

# save path on cd
function cd {
    builtin cd $@
    pwd > ~/.last_dir

# restore last saved path
if [ -f ~/.last_dir ]
    then cd `cat ~/.last_dir`

inside my .zshrc

share|improve this answer
i'm using #1 solution too and add trap "[ -f ~/.last_dir ] && rm ~/.last_dir" EXIT i want start always in my home except when i open a new tab – rkmax Jul 12 '13 at 21:18
This is a useful enhancement, thanks – Luca May 26 '14 at 11:17

Of course it is a working approach to modify cd's behavior, but I would like to show a more simple solution. In the man bash(1) I found that if an interactive exits it runs ~/.bash_logout if exists. So instead of storing the path at every invocation of cd the last path can be saved at exit.

My ~/.bash_logout is very simple:

echo $PWD >~/.lastdir

And somewhere in my .bashrc I placed this line:

[ -r ~/.lastdir ] && cd $(<~/.lastdir)

I hope this helps a bit!

share|improve this answer
Just note that .bash_logout runs only when login shells exit, that's not always the case. – henfiber Jun 23 '15 at 4:46
Alternatively, save the last path when bash exits with : trap "echo $PWD > ~/.lastdir" EXIT" – henfiber Jun 23 '15 at 5:02
@henfiber Thanks for your comments! I think in this case the shell is a login shell, so this will behave properly. On the other hand the trap approach is also nice, I like it! – TrueY Jun 23 '15 at 7:18

Just add . /etc/profile.d/vte.sh in your ~/.bashrc to get the same feature

share|improve this answer
This work, however, why bother -1 this? – Abdillah Feb 17 '15 at 6:51
This works, and it looks like it's actually the preferred solution on launchpad / of gnome-terminal devs: bugs.launchpad.net/ubuntu/+source/gnome-terminal/+bug/1132700 – Ajax Apr 5 '15 at 23:19

Very often I use multiple terminal windows at once, each with multiple tabs in it. For example: one window for source code development tabs, one window for latex files, one window for R execution and scripting, etc. Within one window, I want a new tabbed terminal to change to the directory which is used last in that particular window (this used to work in the past, but with the new gnome version, somehow it doesn't). The following dirty solution works fine for me. I have put this in .bashrc.

[ -r "$dirfilename" ] &&  {
    savdir=`cat $dirfilename`
    cd "$savdir"

function cd ()
    builtin cd "$@"
    echo $PWD > $dirfilename
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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