Do we have more history for cd?
Solution 1
The command you are looking for is pushd
and popd
.
You could view a practical working example of pushd
and popd
from here.
mkdir /tmp/dir1
mkdir /tmp/dir2
mkdir /tmp/dir3
mkdir /tmp/dir4
cd /tmp/dir1
pushd .
cd /tmp/dir2
pushd .
cd /tmp/dir3
pushd .
cd /tmp/dir4
pushd .
dirs
/tmp/dir4 /tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1
Solution 2
You didn't specify which shell you are using, so let this be excuse to advertise zsh.
Yes, we do have more history for cd
, namely cd -2
, cd -4
etc. Very convenient is cd -
TAB, especially with completion system and colors enabled:
This is what I have in .zshrc:
setopt AUTO_PUSHD # pushes the old directory onto the stack
setopt PUSHD_MINUS # exchange the meanings of '+' and '-'
setopt CDABLE_VARS # expand the expression (allows 'cd -2/tmp')
autoload -U compinit && compinit # load + start completion
zstyle ':completion:*:directory-stack' list-colors '=(#b) #([0-9]#)*( *)==95=38;5;12'
And the result:
Solution 3
To answer your question regarding "more history". No the cd -
feature in Bash only supports a single directory that you can "flip" back to. As @Ramesh states in his answer. If you want a longer history of directories you can use pushd
and popd
to save a directory or return to a previous one.
You can also see the list of what's currently in the stack with the dirs
command.
A detailed explanation can be found from this answer titled: How do I use pushd and popd commands?.
Solution 4
You have as much history as you want:
cd() {
[ "$((${DIRSTACKMAX##*[!0-9]*}0/10))" -gt 0 ] &&
set -- "$@" "$DIRSTACK" &&
DIRSTACK='pwd -P >&3; command cd' ||
{ command cd "$@"; return; }
_q() while case "$1" in (*\'*) : ;; (*)
! DIRSTACK="$DIRSTACK '$2$1'" ;;esac
do set -- "${1#*\'}" "$2${1%%\'*}'\''"
done
while [ "$#" -gt 1 ]
do case ${1:---} in (-|[!-]*|-*[!0-9]*) : ;;
(*) eval " set $((${1#-}+1))"' "${'"$#}\""
eval ' set -- "$2"'" $2"'
set -- "${'"$1"'}" "$1"'
;;esac; _q "$1"; shift
done
eval " DIRSTACK=; $DIRSTACK &&"'
_q "$OLDPWD" &&
DIRSTACK=$DIRSTACK\ $1
set "$?" "${DIRSTACK:=$1}"'" $1
" 3>/dev/null
[ "$(($#-1))" -gt "$DIRSTACKMAX" ] &&
DIRSTACK="${DIRSTACK% \'/*}"
unset -f _q; return "$1"
}
That's a shell function that should enable any POSIX compatible shell to offer zsh
-style cd
history. It does all of its work without invoking a single subshell, and I believe its flow is pretty sound - it seems to handle all cases correctly under moderate testing.
The function attempts to play as nicely with its environment as it may while still relying on fully portable syntax - it makes only one assumption and that is that the $DIRSTACK
environment variable is its property to do with as it will.
It canonicalizes all paths that it stores in $DIRSTACK
and serializes all of them on single-quotes - though it ensures each is safely quoted and serialized before adding it to the value of the variable and shouldn't have any issue with any special characters of any kind. If the $DIRSTACKMAX
environment variable is set it will use it as an upper limit for the number of paths it retains in history, else the limit is one.
If you load the function you just cd
as normal but will also be able to do the cd -[num]
for retracing back through your change directory history.
The function's primary mechanism is cd
itself - and the ${OLD,}PWD
environment variables. POSIX specifies that cd
change these for every path move - and so this just uses the shell's builtin variables and saves the values for as long as you like.
Solution 5
You can install and use my dirhistory utility for bash.
Basically, it's a daemon that collects directory changes from all your shells, and a Cdk program that displays the history and lets you pick any directory to switch to (so you're not limited to a stack).
Related videos on Youtube
![Tim](https://i.stack.imgur.com/3PCjR.png?s=256&g=1)
Tim
Elitists are oppressive, anti-intellectual, ultra-conservative, and cancerous to the society, environment, and humanity. Please help make Stack Exchange a better place. Expose elite supremacy, elitist brutality, and moderation injustice to https://stackoverflow.com/contact (complicit community managers), in comments, to meta, outside Stack Exchange, and by legal actions. Push back and don't let them normalize their behaviors. Changes always happen from the bottom up. Thank you very much! Just a curious self learner. Almost always upvote replies. Thanks for enlightenment! Meanwhile, Corruption and abuses have been rampantly coming from elitists. Supportive comments have been removed and attacks are kept to control the direction of discourse. Outright vicious comments have been removed only to conceal atrocities. Systematic discrimination has been made into policies. Countless users have been harassed, persecuted, and suffocated. Q&A sites are for everyone to learn and grow, not for elitists to indulge abusive oppression, and cover up for each other. https://softwareengineering.stackexchange.com/posts/419086/revisions https://math.meta.stackexchange.com/q/32539/ (https://i.stack.imgur.com/4knYh.png) and https://math.meta.stackexchange.com/q/32548/ (https://i.stack.imgur.com/9gaZ2.png) https://meta.stackexchange.com/posts/353417/timeline (The moderators defended continuous harassment comments showing no reading and understanding of my post) https://cs.stackexchange.com/posts/125651/timeline (a PLT academic had trouble with the books I am reading and disparaged my self learning posts, and a moderator with long abusive history added more insults.) https://stackoverflow.com/posts/61679659/revisions (homework libels) Much more that have happened.
Updated on September 18, 2022Comments
-
Tim almost 2 years
cd -
can move to the last visited directory. Can we visit more history other than the last one?-
Gilles 'SO- stop being evil' over 9 years
-
-
Ramesh over 9 yearsI have included a reference from your answer. Hope you don't mind. :)
-
jimmij over 9 yearsOK, I won't delete this answer, maybe will be useful for others.
-
yieldsfalsehood over 9 yearsUnless the question specifically asks about
bash
, this is a valid answer. Don't remove it. -
mechalynx over 9 yearsThere's also
$OLDPWD
in case you want to flip back and forth between two directories using the same command, but I'm unsure how shell-specific and distribution/kernel-specific this is. -
Ooker over 9 yearsWhat if the OP edits his question to include bash only, will this answer still be valid?
-
Gilles 'SO- stop being evil' over 9 years@ivy_lynx
OLDPWD
exists in all POSIX shells, but it's useless for this question which asks how to go beyond that (the question already mentionscd -
which is a shortcut forcd "$OLDPWD"
). -
alexis over 9 yearsNice feature, didn't know this about zsh.
-
Dave Rayner over 9 years@Ooker that's discussed in detail somewhere on meta.SO or meta.SE, but in this case I would say yes because it's still very useful, and even worthwhile to say "this feature could be implemented because it exists here."
-
GnP over 9 yearsIs there a reason you use
cd /tmp/dir1; pushd .
instead of justpushd /tmp/dir1
? -
Ramesh over 9 years@gnp, no specific reason. It was just taken from the link that I have referred to in the answer.
pushd /tmp/dir1
should work just fine. -
GnP over 9 yearsOk, just picked my curiosity. I'd like to suggest you improve your answer with an actual example using
pushd
andpopd
to traverse a directory tree back and forth. Your answer is already the correct one. -
wjv about 8 yearsIt might bear mentioning that apart from
setopt AUTO_PUSHD
, none of the above setup is required to get an omnipresent directory stack with completion in stock zsh.PUSHD_MINUS
reverses the sense ofcd +
andcd -
(a matter of taste),CDABLE_VARS
is irrelevant to directory stacks, and thezstyle
invocation given here simply adds colouring to the output of a directory stack completion. One must however initialise the completion subsystem withautoload -U compinit && compinit
. -
mikeserv over 7 years@datUser - i knew someone had a dat. youre quite welcome
-
ddnomad about 7 yearsHm, looks promising. I'll check it out.
-
jo_ about 7 years
-
rmbianchi over 3 yearsGreat! I didn't know about this specific feature of zsh! Thanks a lot for the hint! +1