5

I am a happy user of the cd - command to go to the previous directory. At the same time I like pushd . and popd.

However, when I want to remember the current working directory by means of pushd ., I lose the possibility to go to the previous directory by cd -. (As pushd . also performs cd .).

How can I use pushd to still be able to use cd -

By the way: GNU bash, version 4.1.7(1)

7
  • 1
    Why not use pwd to figure out where you are? Commented Feb 21, 2012 at 12:39
  • I don't understand your question? The point is that pushd breaks the behavior of cd - that I want (or expect). I know perfectly well in which directory I am, but I want to increase the speed with which I change directories :) Commented Feb 21, 2012 at 12:46
  • 1
    Do you know zsh? It has really nice features like AUTO_PUSHD. Commented Feb 21, 2012 at 14:39
  • 3
    +1 Thank you for teaching me about cd -! For most of a decade, I've been doing $ cd $OLDPWD instead. Commented Feb 21, 2012 at 16:26
  • 1
    @bernhard Oh, I misunderstood what you were asking. You were wanting to know how to store the current working directory. I was interpreting it as you wanted to remember (as in you forgot) your current working directory. Commented Feb 22, 2012 at 1:58

3 Answers 3

7

You can use something like this:

push() { if [ "$1" = . ]; then old=$OLDPWD current=$PWD builtin pushd . cd "$old" cd "$current" else builtin pushd "$1" fi } 

If you name it pushd, then it will have precedence over the built-in as functions are evaluated before built-ins.

You need variables old and current as overwriting OLDPWD will make it lose its special meaning.

3
  • This works perfectly for me. Is there no such feature in the built-in pushd? As I would always prefer a standard solution. Thanks for this function however, maybe I will leave out the argument and it's checking at some point. Commented Feb 21, 2012 at 12:41
  • There is no such feature in the builtin. Your own function is the best solution because pushd and popd both call cd modifying $OLDPWD, hence the source of your problem. I would name the function saved and use it in the context you like too, that of saving cwd. Commented Feb 21, 2012 at 12:53
  • You might also want to unset old and current after you're done with them. Commented Mar 29, 2016 at 23:08
3

A slightly more concise version of Wojtek's answer:

pushd () { if [ "$1" = . ]; then cd - builtin pushd - else builtin pushd "$1" fi } 

By naming the function pushd, you can use pushd as normal, you don't need to remember to use the function name.

0

Kevin's answer is excellent. I've written up some details about what's going on, in case people are looking for a better understanding of why their script is necessary to solve the problem.

The reason that pushd . breaks the behavior of cd - will be apparent if we dig into the workings of cd and the directory stack. Let's push a few directories onto the stack:

$ mkdir dir1 dir2 dir3 $ pushd dir1 ~/dir1 ~ $ pushd../dir2 ~/dir2 ~/dir1 ~ $ pushd../dir3 ~/dir3 ~/dir2 ~/dir1 ~ $ dirs -v 0 ~/dir3 1 ~/dir2 2 ~/dir1 3 ~ 

Now we can try cd - to jump back a directory:

$ cd - /home/username/dir2 $ dirs -v 0 ~/dir2 1 ~/dir2 2 ~/dir1 3 ~ 

We can see that cd - jumped us back to the previous directory, replacing stack ~0 with the directory we jumped into. We can jump back with cd - again:

$ cd - /home/username/dir3 $ dirs -v 0 ~/dir3 1 ~/dir2 2 ~/dir1 3 ~ 

Notice that we jumped back to our previous directory, even though the previous directory wasn't actually listed in the directory stack. This is because cd uses the environment variable $OLDPWD to keep track of the previous directory:

$ echo $OLDPWD /home/username/dir2 

If we do pushd . we will push an extra copy of the current directory onto the stack:

$ pushd . ~/dir3 ~/dir3 ~/dir2 ~/dir1 ~ $ dirs -v 0 ~/dir3 1 ~/dir3 2 ~/dir2 3 ~/dir1 4 ~ 

In addition to making an extra copy of the current directory in the stack, pushd . has updated $OLDPWD:

$echo $OLDPWD /home/username/dir3 

So cd - has lost its useful history, and will now just move you to the current directory - accomplishing nothing.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.