|
Home | Switchboard | Unix Administration | Red Hat | TCP/IP Networks | Neoliberalism | Toxic Managers |
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and bastardization of classic Unix |
|
|
Extracted from Professor Nikolai Bezroukov unpublished lecture notes.
Copyright 2010-2018, Dr. Nikolai Bezroukov. This is a fragment of the copyrighted unpublished work. All rights reserved.
Everybody on intuitive level understand that cd command in not the best way to navigate complex maze of directories which are common in modern filesystems.
The first alternative to cd command, which was initially introduced iin C-shell in late 70th were pushd/popd/dirs troika. Those commands operate on a stack of directories with pushd adding elements to the stack and performing cd to this directory, and popd removing the top element from the stack and also perofming cd to this directory. Bash implementation of dirs is buggy in a sense that it does not accept multiple options like any linux command should (so dirs -lv produces an error while dirs -l -v does not)
While improvement over cd command, the semantic of this pushd/popd/dirs troika poorly though out and due to this commands are much less useful then they should be. But they can be used productively, despite their shortcomings by imitating list of favorites. In other words what we need is the list of directory favorites not dynamic directories stack.
Despite the fact that the cd command is a bash built-in, bash does not maintain separate history of visited directories.
The way to accomplish this created you private list of favorite directories and then populate the stack fro this list and keep it "as it" until you add of remove a directory from this list:
/bin/rm ~/.fav; dirs -c; cat ~/fav.lst | xargs -rn 1 echo pushd -n >> ~/.fav; . ~/.fav; dirs -v
To make this operation more convenient you can create function or and alias from this rather complex command line:
alias fav='/bin/rm ~/.fav; dirs -c; cat ~/fav.lst | xargs -rn 1 echo pushd -n >> ~/.fav; . ~/.fav 1>/dev/null; dirs -v'
After you can define function (for example go) which switch to the N directory from the top of your stack. For example:
function jmp { cd `dirs -l +$1` }
In other words the idea is to use dirs -l -v command to list content of the static stack containing your directory favorites. If the directory is in you list you can cd to the selected by typing its number. Generally you can avoid using popd at all. In this arrangements this is a useless command.
To populate the directory you can use command history (if you do not delete from it cd commands) but the problem with this solution is that in command history directories are seldom typed with absolute path. Instead the additions to the list of favorites can done via bash PROMPT_COMMAND string which specifies function executed each time you press Enter key and submit command for execution. For example in the function which is called via bash PROMPT_COMMAND setting you can have the following statement:
if [[ "x$PWD" != "x$PREVPWD" ]]: then echo $PWD >> ~/.dir_history } export PREVPWD=$PWD
You can be more adventurous and provide a single command which first dynamically created the list of favorite directories and then asks for the the number in this list of the directory to which you want to go:
# Nikolai Bezroukov, 2018 function go { cat ~/fav_static.lst > ~/fav.lst sort ~/.dir_history | uniq -c | sort -rn | cut -c 9- | head -7 >> ~/fav.lst # most frequent tail -5 ~/.dir_history >> ~/fav.lst # last used /bin/rm ~/.fav; dirs -c; cat ~/fav.lst | xargs -rn 1 echo pushd -n >> ~/.fav; . ~/.fav 1>/dev/null; dirs -v -l if (( $# > 0 )); then mydir=`dirs -l +$1` cd $mydir else echo -n 'Select the directory number in favorites: ' read target if [[ $target =~ \-[0-9]+ ]]; then echo $target let target=13+$target mydir=`dirs -l +$target` cd $mydir elif [[ target =~ [0-9]+ ]]; then echo +$target mydir=`dirs -l +$target` cd $mydir else echo ERROR: wrong target $target fi fi }
In the very simple implementation above the list of favorite directories is a composite consisting of three parts:
One advantage of this implementation is that the list of favorites is stired inthe array use by push/dirs commands and is availble with any of those commands too for example via function jmp descibed above
function jmp { cd `dirs -l +$1` }
Of course this implementation can be enhanced, but even in this primitive form it is really useful if you regularly deals with the deeply nested directories. I created it for working with genomic files.
Of course, you can move updates of the directories and creation of the .fav file for sourcing into your environment to cron (in this case the only thing you need in go function is to source .fav), but modern servers are so fast that those operation are instant anyway
dirs - execution of this command does not change the state of the stack. If you need to go to, say, firth command from the top of the stack without changing stack you can use the command cd `dirs -l +5`
dirs has 7 parameters (note that options should be specified individually -- dirs does not understand "bungled" options format):
dirs [+N | -N] [-clvp]
- +N -- Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
- -N -- Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
- -c Clears the directory stack by deleting all of the elements except the current directory which became the only element of the stack.
- -l - Produces a longer listing expanding the value of "~" (tilde); the default listing format uses a tilde to denote the home directory at the moment of execution of the command.
- -p -- Causes dirs to print the directory stack with one entry per line.
- -v -- Causes dirs to print the directory stack with one entry per line, prefixing each entry with its index in the stack.
pushd [dir | +N | -N] [-n]
- +N
- Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. cd to this directory
- -N
- Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. cd to this directory.
- -n Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. Can be used to populating the stack
- dir
- Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir'. cds to dir.
Dr. Nikolai Bezroukov
Jul 12, 2020 | opensource.com
Navigating the Bash shell with pushd and popd Pushd and popd are the fastest navigational commands you've never heard of. 07 Aug 2019 Seth Kenlon (Red Hat) Feed 71 up 7 comments Image by : Opensource.com x Subscribe now
Get the highlights in your inbox every week.
https://opensource.com/eloqua-embedded-email-capture-block.html?offer_id=70160000000QzXNAA0
The pushd and popd commands are built-in features of the Bash shell to help you "bookmark" directories for quick navigation between locations on your hard drive. You might already feel that the terminal is an impossibly fast way to navigate your computer; in just a few key presses, you can go anywhere on your hard drive, attached storage, or network share. But that speed can break down when you find yourself going back and forth between directories, or when you get "lost" within your filesystem. Those are precisely the problems pushd and popd can help you solve.
pushdAt its most basic, pushd is a lot like cd . It takes you from one directory to another. Assume you have a directory called one , which contains a subdirectory called two , which contains a subdirectory called three , and so on. If your current working directory is one , then you can move to two or three or anywhere with the cd command:
$ pwd
one
$ cd two / three
$ pwd
threeYou can do the same with pushd :
$ pwd
one
$ pushd two / three
~ / one / two / three ~ / one
$ pwd
threeThe end result of pushd is the same as cd , but there's an additional intermediate result: pushd echos your destination directory and your point of origin. This is your directory stack , and it is what makes pushd unique.
StacksA stack, in computer terminology, refers to a collection of elements. In the context of this command, the elements are directories you have recently visited by using the pushd command. You can think of it as a history or a breadcrumb trail.
You can move all over your filesystem with pushd ; each time, your previous and new locations are added to the stack:
$ pushd four
~ / one / two / three / four ~ / one / two / three ~ / one
$ pushd five
~ / one / two / three / four / five ~ / one / two / three / four ~ / one / two / three ~ / one Navigating the stackOnce you've built up a stack, you can use it as a collection of bookmarks or fast-travel waypoints. For instance, assume that during a session you're doing a lot of work within the ~/one/two/three/four/five directory structure of this example. You know you've been to one recently, but you can't remember where it's located in your pushd stack. You can view your stack with the +0 (that's a plus sign followed by a zero) argument, which tells pushd not to change to any directory in your stack, but also prompts pushd to echo your current stack:
$ pushd + 0
~ / one / two / three / four ~ / one / two / three ~ / one ~ / one / two / three / four / fiveAlternatively, you can view the stack with the dirs command, and you can see the index number for each directory by using the -v option:
$ dirs -v
0 ~ / one / two / three / four
1 ~ / one / two / three
2 ~ / one
3 ~ / one / two / three / four / fiveThe first entry in your stack is your current location. You can confirm that with pwd as usual:
$ pwd
~ / one / two / three / fourStarting at 0 (your current location and the first entry of your stack), the second element in your stack is ~/one , which is your desired destination. You can move forward in your stack using the +2 option:
$ pushd + 2
~ / one ~ / one / two / three / four / five ~ / one / two / three / four ~ / one / two / three
$ pwd
~ / oneThis changes your working directory to ~/one and also has shifted the stack so that your new location is at the front.
You can also move backward in your stack. For instance, to quickly get to ~/one/two/three given the example output, you can move back by one, keeping in mind that pushd starts with 0:
$ pushd -0
~ / one / two / three ~ / one ~ / one / two / three / four / five ~ / one / two / three / four Adding to the stackYou can continue to navigate your stack in this way, and it will remain a static listing of your recently visited directories. If you want to add a directory, just provide the directory's path. If a directory is new to the stack, it's added to the list just as you'd expect:
$ pushd / tmp
/ tmp ~ / one / two / three ~ / one ~ / one / two / three / four / five ~ / one / two / three / fourBut if it already exists in the stack, it's added a second time:
$ pushd ~ / one
~ / one / tmp ~ / one / two / three ~ / one ~ / one / two / three / four / five ~ / one / two / three / fourWhile the stack is often used as a list of directories you want quick access to, it is really a true history of where you've been. If you don't want a directory added redundantly to the stack, you must use the +N and -N notation.
Removing directories from the stackYour stack is, obviously, not immutable. You can add to it with pushd or remove items from it with popd .
For instance, assume you have just used pushd to add ~/one to your stack, making ~/one your current working directory. To remove the first (or "zeroeth," if you prefer) element:
$ pwd
~ / one
$ popd + 0
/ tmp ~ / one / two / three ~ / one ~ / one / two / three / four / five ~ / one / two / three / four
$ pwd
~ / oneOf course, you can remove any element, starting your count at 0:
$ pwd ~ / one
$ popd + 2
/ tmp ~ / one / two / three ~ / one / two / three / four / five ~ / one / two / three / four
$ pwd ~ / oneYou can also use popd from the back of your stack, again starting with 0. For example, to remove the final directory from your stack:
$ popd -0
/ tmp ~ / one / two / three ~ / one / two / three / four / fiveWhen used like this, popd does not change your working directory. It only manipulates your stack.
Navigating with popdThe default behavior of popd , given no arguments, is to remove the first (zeroeth) item from your stack and make the next item your current working directory.
This is most useful as a quick-change command, when you are, for instance, working in two different directories and just need to duck away for a moment to some other location. You don't have to think about your directory stack if you don't need an elaborate history:
$ pwd
~ / one
$ pushd ~ / one / two / three / four / five
$ popd
$ pwd
~ / oneYou're also not required to use pushd and popd in rapid succession. If you use pushd to visit a different location, then get distracted for three hours chasing down a bug or doing research, you'll find your directory stack patiently waiting (unless you've ended your terminal session):
$ pwd ~ / one
$ pushd / tmp
$ cd { / etc, / var, / usr } ; sleep 2001
[ ... ]
$ popd
$ pwd
~ / one Pushd and popd in the real worldThe pushd and popd commands are surprisingly useful. Once you learn them, you'll find excuses to put them to good use, and you'll get familiar with the concept of the directory stack. Getting comfortable with pushd was what helped me understand git stash , which is entirely unrelated to pushd but similar in conceptual intangibility.
Using pushd and popd in shell scripts can be tempting, but generally, it's probably best to avoid them. They aren't portable outside of Bash and Zsh, and they can be obtuse when you're re-reading a script ( pushd +3 is less clear than cd $HOME/$DIR/$TMP or similar).
Aside from these warnings, if you're a regular Bash or Zsh user, then you can and should try pushd and popd . Bash prompt tips and tricks Here are a few hidden treasures you can use to customize your Bash prompt. Dave Neary (Red Hat) Topics Bash Linux Command line About the author Seth Kenlon - Seth Kenlon is an independent multimedia artist, free culture advocate, and UNIX geek. He has worked in the film and computing industry, often at the same time. He is one of the maintainers of the Slackware-based multimedia production project, http://slackermedia.info More about me Recommended reading
Add videos as wallpaper on your Linux desktop
Use systemd timers instead of cronjobs
Why I stick with xterm
Customizing my Linux terminal with tmux and Git
Back up your phone's storage with this Linux utility
Read and write data from anywhere with redirection in the Linux terminal 7 Comments
matt on 07 Aug 2019
Seth Kenlon on 07 Aug 2019Thank you for the write up for pushd and popd. I gotta remember to use these when I'm jumping around directories a lot. I got a hung up on a pushd example because my development work using arrays differentiates between the index and the count. In my experience, a zero-based array of A, B, C; C has an index of 2 and also is the third element. C would not be considered the second element cause that would be confusing it's index and it's count.
Greg Pittman on 07 Aug 2019Interesting point, Matt. The difference between count and index had not occurred to me, but I'll try to internalise it. It's a great distinction, so thanks for bringing it up!
Seth Kenlon on 07 Aug 2019This looks like a recipe for confusing myself.
Jake on 07 Aug 2019It can be, but start out simple: use pushd to change to one directory, and then use popd to go back to the original. Sort of a single-use bookmark system.
Then, once you're comfortable with pushd and popd, branch out and delve into the stack.
A tcsh shell I used at an old job didn't have pushd and popd, so I used to have functions in my .cshrc to mimic just the back-and-forth use.
Seth Kenlon on 07 Aug 2019"dirs" can be also used to view the stack. "dirs -v" helpfully numbers each directory with its index.
other_Stu on 11 Aug 2019Thanks for that tip, Jake. I arguably should have included that in the article, but I wanted to try to stay focused on just the two {push,pop}d commands. Didn't occur to me to casually mention one use of dirs as you have here, so I've added it for posterity.
There's so much in the Bash man and info pages to talk about!
I use "pushd ." (dot for current directory) quite often. Like a working directory bookmark when you are several subdirectories deep somewhere, and need to cd to couple of other places to do some work or check something.
And you can use the cd command with your DIRSTACK as well, thanks to tilde expansion.
cd ~+3 will take you to the same directory as pushd +3 would.
Apr 10, 2012 | github.com
autojump is a faster way to navigate your filesystem. It works by maintaining a database of the directories you use the most from the command line.
Directories must be visited first before they can be jumped to. USAGE
j is a convenience wrapper function around autojump. Any option that can be used with autojump can be used with j and vice versa.
- Jump To A Directory That Contains foo:
j foo- Jump To A Child Directory:
Sometimes it's convenient to jump to a child directory (sub-directory of current directory) rather than typing out the full name.
jc bar- Open File Manager To Directories (instead of jumping):
Instead of jumping to a directory, you can open a file explorer window (Mac Finder, Windows Explorer, GNOME Nautilus, etc.) to the directory instead.
jo musicOpening a file manager to a child directory is also supported:
jco images- Using Multiple Arguments:
Let's assume the following database:
30 /home/user/mail/inbox 10 /home/user/work/inboxj in would jump into /home/user/mail/inbox as the higher weighted entry. However you can pass multiple arguments to autojump to prefer a different entry. In the above example, j w in would then change directory to /home/user/work/inbox.
For more options refer to help:
autojump --helpKNOWN ISSUES
-
- autojump does not support directories that begin with -.
-
- For bash users, autojump keeps track of directories by modifying $PROMPT_COMMAND. Do not overwrite $PROMPT_COMMAND:
export PROMPT_COMMAND="history -a"Instead append to the end of the existing $PROMPT_COMMAND:
REPORTING BUGS
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ;} history -a"For any questions or issues please visit:
AUTHORS
https://github.com/joelthelion/autojump/issuesautojump was originally written by JoΓ"l Schaerer, and currently maintained by William Ting. More contributors can be found in AUTHORS. COPYRIGHT
Copyright Β© 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later < http://gnu.org/licenses/gpl.html >. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
Oct 14, 2018 | www.hanselman.com
September 18, '14
There's a lovely little utility called autojump for *nix consoles that makes the 'cd' command very smart. More that just auto-completion, it's a kind of "auto guessing." Hence, autojump. There is some beginning Windows support, but instead I turned to Tim Kellogg's open source PowerShell implementation " Jump-Location ."
What a joy.
First, I was like "jump-location?" I'm not going to type that. But then, of course, duh. Aliases.
Jump-Location is aliased to just j , which means I can now do awesome stuff like this:
c:\> j sc c:\users\scott> j g c:\users\AppData\Local\GitHub> j des c:\users\scott\Desktop>But there's more. It's actually watching how long you are in a directory and keeping stats. You can see the weighted stats with "jumpstat" and the "database" is just a text file in ~\jump-location.txt.
If "j d" isn't enough to get me into C:\GitHub\DisProject then I can do "j g d" and I'm there. It's amazing.
Installation is easy, and I hope it gets on PsGet soon for even easier installation. Just unzip, unblock, ensure that your PowerShell execution policy allows scripts, and run ./install.ps1.
NOTE : Don't run install from your desktop, or a temp folder. Put the Jump-Location folder somewhere where it will live, and it's going to add a line like this to your user profile ("C:\Users\YOU\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1") like this, so you'll want to install from a final path:
Import-Module 'C:\Users\Scott\Dropbox\utils\Jump-Location-0.5.1\Jump.Location.psd1'I'm excited about this great little utility. Head over to https://github.com/tkellogg/Jump-Location and STAR it in GitHub, and give it a go! Tim, the author, is on Twitter at @kellogh . Other contributors include Sergey Vorobyev .
Oct 14, 2018 | www.linuxquestions.org
05-02-2017, 04:19 AM # 1 deepcore LQ Newbie
Registered: Dec 2005 Location: Denmark, Copenhagen Distribution: Ubuntu Ultimate v.6 Posts: 10
Rep:Port of NCD (Norton Change Directory) for debian/ubuntu
[ Log in to get rid of this advertisement] Does anyone know of a current port of ncd (Norton Change Directory) for Debian/Ubuntu systems? Preferably accessible through the package manager so it can easily be added to newly installed systems.My best effords to find a similar utility has led me to:
https://github.com/KellyLSB/KCD
http://kcd.sourceforge.net/
https://waterlan.home.xs4all.nl/... but as stated i would like to have it from packagemanager.
deepcore View Public Profile View LQ Blog View Review Entries View HCL Entries Find More Posts by deepcore
05-02-2017, 04:48 AM # 2 pan64 LQ Guru
Registered: Mar 2012 Location: Hungary Distribution: debian/ubuntu/suse ... Posts: 11,334
Rep:I don't know what do you really need, but for example zsh has a built-in cd command which has a lot of features (although a bit different).
pan64 View Public Profile View LQ Blog View Review Entries View HCL Entries Find More Posts by pan64
05-02-2017, 05:26 AM # 3 michaelk Moderator
Registered: Aug 2002 Posts: 17,578
Rep:What about wcd? It should be available in the debian/Ubuntu repositories.
Sep 27, 2018 | unix.stackexchange.com
Conflict between `pushd .` and `cd -` Ask Question up vote 5 down vote favorite 1
Bernhard ,Feb 21, 2012 at 12:07
I am a happy user of thecd -
command to go to the previous directory. At the same time I likepushd .
andpopd
.However, when I want to remember the current working directory by means of
pushd .
, I lose the possibility to go to the previous directory bycd -
. (Aspushd .
also performscd .
).How can I use
pushd
to still be able to usecd -
By the way: GNU bash, version 4.1.7(1)
Patrick ,Feb 21, 2012 at 12:39
Why not usepwd
to figure out where you are? Patrick Feb 21 '12 at 12:39Bernhard ,Feb 21, 2012 at 12:46
I don't understand your question? The point is that pushd breaks the behavior ofcd -
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 :) Bernhard Feb 21 '12 at 12:46jofel ,Feb 21, 2012 at 14:39
Do you knowzsh
? It has really nice features like AUTO_PUSHD. jofel Feb 21 '12 at 14:39Theodore R. Smith ,Feb 21, 2012 at 16:26
+1 Thank you for teaching me about cd -! For most of a decade, I've been doing $ cd $OLDPWD instead. Theodore R. Smith Feb 21 '12 at 16:26Patrick ,Feb 22, 2012 at 1:58
@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. Patrick Feb 22 '12 at 1:58Wojtek Rzepala ,Feb 21, 2012 at 12:32
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
andcurrent
as overwritingOLDPWD
will make it lose its special meaning.Bernhard ,Feb 21, 2012 at 12:41
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. Bernhard Feb 21 '12 at 12:41bsd ,Feb 21, 2012 at 12:53
There is no such feature in the builtin. Your own function is the best solution because pushd and popd both callcd
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. bsd Feb 21 '12 at 12:53Wildcard ,Mar 29, 2016 at 23:08
You might also want to unsetold
andcurrent
after you're done with them. Wildcard Mar 29 '16 at 23:08Kevin ,Feb 21, 2012 at 16:11
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 usepushd
as normal, you don't need to remember to use the function name.,
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 ofcd -
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 withcd -
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/dir2If 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/dir3So
cd -
has lost its useful history, and will now just move you to the current directory - accomplishing nothing.
Sep 26, 2018 | unix.stackexchange.com
chrisjlee ,Feb 9, 2012 at 6:24
Afterpushd
ing too many times, I want to clear the whole stack of paths.How would I
popd
all the items in the stack?I'd like to
popd
without needing to know how many are in the stack?The bash manual doesn't seem to cover this .
Why do I need to know this? I'm fastidious and to clean out the stack.
jw013 ,Feb 9, 2012 at 6:39
BTW, the complete bash manual is over at gnu.org. If you use the all on one page version, it may be easier to find stuff there. – jw013 Feb 9 '12 at 6:39jw013 ,Feb 9, 2012 at 6:37
dirs -c
is what you are looking for.Eliran Malka ,Mar 23, 2017 at 15:20
this does empty the stack, but does not restore the working directory from the stack bottom – Eliran Malka Mar 23 '17 at 15:20Eliran Malka ,Mar 23, 2017 at 15:37
In order to both empty the stack and restore the working directory from the stack bottom, either:
- retrieve that directory from
dirs
, change to that directory, and than clear the stack:cd "$(dirs -l -0)" && dirs -cThe
-l
option here will list full paths, to make sure we don't fail if we try tocd
into~
, and the-0
retrieves the first entry from the stack bottom.@jw013 suggested making this command more robust, by avoiding path expansions:
pushd -0 && dirs -c- or,
popd
until you encounter an error (which is the status of apopd
call when the directory stack is empty):while (( $? == 0 )); do popd; doneChuck Wilbur ,Nov 14, 2017 at 18:21
The first method is exactly what I wanted. The second wouldn't work in my case since I had calledpushd
a few times, then removed one of the directories in the middle, thenpopd
was failing when I tried to unroll. I needed to jump over all the buggered up stuff in the middle to get back to where I started. – Chuck Wilbur Nov 14 '17 at 18:21Eliran Malka ,Nov 14, 2017 at 22:51
right @ChuckWilbur - if you scrambled the dir stack,popd
won't save you :) – Eliran Malka Nov 14 '17 at 22:51jw013 ,Dec 7, 2017 at 20:50
It's better topushd -0
instead ofcd "$(dirs ...)"
. – jw013 Dec 7 '17 at 20:50Eliran Malka ,Dec 11, 2017 at 13:56
@jw013 how so? that would mess with the dir stack even more (which we're trying to clear here..) – Eliran Malka Dec 11 '17 at 13:56jw013 ,Dec 12, 2017 at 15:31
cd "$(...)"
works in 90%, probably even 99% of use cases, but withpushd -0
you can confidently say 100%. There are so many potential gotchas and edge cases associated with expanding file/directory paths in the shell that the most robust thing to do is just avoid it altogether, whichpushd -0
does very concisely.There is no chance of getting caught by a bug with a weird edge case if you never take the risk. If you want further reading on the possible headaches involved with Unix file / path names, a good starting point is mywiki.wooledge.org/ParsingLs – jw013 Dec 12 '17 at 15:31
April, 2005 | O'Reilly ONLamp Blog
directory stack
Long ago having aliased "pu" and "po" to pushd and popd, I've moved on to showing my current directory stack with
alias d='dirs -v'
and rolling through the stack with
alias r='pushd +1'
and single numerical values aliased to go to that directory that comes from the dir listing, eg.
alias 3='pushd +3 > /dev/null ; dirs -v'
Another single letter alias I like is "p", which I have used for displaying and setting my PATH variable, but the code is lengthy so I won't burden you with how
p - 4
p --
p ++ /some/dir
does what you want.
Roland Mainz roland.mainz at nrubsig.org
Wed Sep 12 09:32:34 PDT 2007
- Previous message: [indiana-discuss] [advocacy-discuss] General Branding Experience for Indiana
- Next message: [indiana-discuss] Fwd: [foss.in] FOSS.IN/2007 Project Days sessions
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi! ---- [Sorry for the late reply, this one was apparently rotting in my Drafts/-folder for a long time... ;-( ] Tim Bray wrote: > On Aug 8, 2007, at 10:56 AM, Richard Elling wrote: > > pushd/popd and dirs came from csh. They are invaluable when you only > > had a terminal. They are so invaluable that ksh code to implement > > them > > is on pp 244-247 of "The Kornshell Command and Programming > > Language" by > > Bolsky and Korn, ISBN 0-13-516972-0. > > Right, well, I have a 24" screen with (at this moment in time) 3 > terminals active, all of which have several directories pushed. > > I'm not religious about shells. I am *passionate* that when we > manage to get a Linux/OS-X user to try Indiana, they don't get rude > shocks in the first three minutes because some basic piece of > infrastructure that's wired into their muscle memory doesn't work. > > If I get on Solaris and !! or !prefix-of-somerevious-command or > pushd/popd doesn't work, *that's a bug*. I don't want to micromanage > how we fix it. -Tim Erm, technically the problem of "pushd/"popd" is that several shells define "pushd" and "popd" with slightly different functionality/options and there is no POSIX specification which could be used as guidance (neither is it possible to just tack-on some functions to the shell without checking whether this is allowed by the POSIX shell spec) ... ... but for interactive ksh93 sessions the solution is AFAIK quite easy: ksh93 has a feature called "FPATH" which specifies a path (similar like the "PATH" variable) from which shell functions can be loaded dynamically at runtime. For ksh93 shipped with Solaris >= 11/B72 in interactive mode this could be used to load the matching functions "pushd"/"popd"/"dirs" from /usr/demo/ksh/fun/ via adding a -- snip -- FPATH+="/usr/demo/ksh/fun/" -- snip -- to /etc/ksh.kshrc BTW: As a mid- or long-term project we'd like to add a larger shell function library at the /usr/lib/shell/ksh/ directory (see CR 6601968 ("RFE: Add /usr/lib/shell/ksh/ as a place to store loadable shell functions")) which would move "pushd"/"popd"/"dirs" out of the demo directory to something like /usr/lib/shell/ksh/org/opensolaris/dirutil/ , giving non-interactive shell scripts a permanent location they can rely on. ---- Bye, Roland
I really like the directory bookmark/browsing ability of tcsh when aliasing the pushd command to cd. Using bash, I would naturally like to have the same abilities, but this turns out to be far from obvious to achieve.The following listing is of a tcsh session displaying the desired functionality:
$ cd dir3 $ dirs 0 ~/tmp/dir1/dir2/dir3 1 ~/tmp/dir1/dir2 2 ~/tmp/dir1 3 ~/tmp $ cd +2 $ pwd /home/user/tmp/dir1 $ dirs 0 ~/tmp/dir1 1 ~/tmp 2 ~/tmp/dir1/dir2/dir3 3 ~/tmp/dir1/dir2 $To get the above behavior a few settings needs to be put into the ~/.tcshrc initializations file:
# .tcshrc alias dirs 'dirs -vl' set dunique set pushdsilent set pushdtohome alias cd 'pushd \!*'Things gets a little complicated when trying to mimic these tcsh settings in bash, because no counterparts exists. This does, of course, not mean that it is not possible, but is does mean that scripting is necessary:
# .bashrc alias dirs='dirs -v' cd() { MAX=10 LEN=${#DIRSTACK[@]} if [ $# -eq 0 ] || [ "$1" = "-" ]; then builtin cd "$@" pushd -n $OLDPWD > /dev/null else pushd "$@" > /dev/null || return 1 fi if [ $LEN -gt 1 ]; then for i in `seq 1 $LEN`; do eval p=~$i if [ "$p" = "$PWD" ]; then popd -n +$i > /dev/null break fi done fi if [ $LEN -ge $MAX ]; then popd -n -0 > /dev/null fi }When this function is put into the ~/.bashrc initialization file, the bash cd command behave exactly as it does in tcsh.
Dave Rutherford
Fri, 15 Jul 2005 21:22:51 -0700On 7/15/05, Ben Horowitz <[EMAIL PROTECTED]> wrote: > I grew to appreciate one feature of tcsh: the ability to use > the commands pushd -v, and popd -v. > > As you know, when the bash pushd and popd commands are successful, > they print the directory stack. In tcsh, one can additionally issue > the command pushd -v, which is like the bash commands pushd followed > by dirs -v. This feature appears not to be available in bash. > > tcsh> pushd -v /tmp > 0 /tmp > 1 / Does this do the trick? pushd () { local verbose=0; if [ "$1" = "-v" ]; then verbose=1; shift; fi; builtin pushd "$@"; if [ $verbose -eq 1 ]; then for w in $@; do echo "$w ${DIRSTACK[$w]}"; done; fi } Barely tested (and with bash 3.0 at that), but it seems to do what you want. popd would be very similar, of course. Dave===Here's a first cut. Salt to taste (yes, you should use getopts): pushd() { local es case "$1" in -v) vflag=y; shift ;; esac builtin pushd "$@" es=$? [ -n "$vflag" ] && dirs -v return $es } -
I was working with linux quite a bit today, and frequently changing between directories, when I wondered if there was a way to go back to the directory I was in previously.
Turns out there is a way:
cd ~-So if I was doing something like this:[pete@bigred /]$ cd /etc [pete@bigred etc]$ cd /usr/local [pete@bigred local]$ cd ~- [pete@bigred etc]$ pwd /etcIf you want to create a command so you don't have to type ~- you can create an alias:alias cdb='cd ~-'This ~- thing works great if you only need to go back one directory, but what if you wanted to go back two directories. Continuing the last code sample:[pete@bigred etc]$ cd ~- [pete@bigred local]$ cd ~- [pete@bigred etc]$ pwd /etcWe are back to /etc and not / our starting point. What I want is something that keeps a history of the directories I've been to.It turns out that the Bash (the "Bourne again shell") has a directory stack builtin. Three command line tools for manipulating the stack are avaliable dirs, pushd, and popd. More info about the directory stack in bash here.
If we pushd a directory onto the directory stack, we can retreive the top of the stack using dirs +1. I tried setting up some aliases to get it to work the way I wanted:
alias cdd='pushd' alias cdb='cd `dirs +1`'Those worked a bit, but I ran into a lot of problems, especially when in the home directory. Also when you run pushd, popd, or dirs it always prints the contents of the stack, I don't know how to suppress that. So I figured I would post it here, and see if anyone can come up with a solution, or if anyone knows of a better way of going about this.Isn't it funny how software developers will spend hours of time trying to save a few seconds of their future time.
On 01/23/2004 at 1:19:30 AM MST John wrote:
cd - works. I don't think you need cd ~-.
On 04/24/2004 at 4:50:56 AM MDT Pritam wrote:
You can suppress the output redirecting the output to /dev/null e.g.
pushd <dir-name> >> /dev/null popd >> /dev/null
On 07/11/2007 at 2:13:43 PM MDT Freddy wrote:
You can use small script from http://fvue.nl/cdots which defines 1-7 dots commands:
$/usr/local/share> ... sh[Tab]
$/usr/share>
Just add the following to your ~/.bashrc or if you want to make this work system wide add this to /etc/bashrc:#redefine pushd and popd so they don't output the directory stack pushd() { builtin pushd "$@" > /dev/null } popd() { builtin popd "$@" > /dev/null } #alias cd so it uses the directory stack alias cd='pushd' #aliad cdb as a command that goes one directory back in the stack alias cdb'popd'The redefinition of pushd and popd redirects their output to /dev/null instead of your terminal. This prevents them from displaying the entire stack every time they are called
Re:pushd and popd (and other tricks) (Score:1)
pushd and popd (and other tricks) (Score:5, Informative)by camh (32881) on Wednesday March 10, @06:25PM (#8526528)
alias pd pushd
alias po popd
Similar to what I have, except I use pp instead of pd (because its faster to type) and pp without args takes you to your home directory (like cd without args). To go along with it, I use
alias r "pushd +1"
alias rr "cd "$OLDPWD"
If you're working within a number of directories, use pp to get to them and then use r to rotate between the directories. rr is convenient to quickly cd somewhere else to do something and then get back again.
by Komi (89040) <[email protected]> on Wednesday March 10, @02:41PM (#8524004)
(http://slashdot.org/)I've read throught the tcsh man pages and stole from other people and probably the least-known most useful trick I've found is pushd and popd (which I realias to pd and po), and of course directory stack substitution. Here's a snippet of code that's really useful: alias pd pushd
alias po popd
cd/incredi/bly/long/path/name
pd/some/other/incredi/bly/long/path/name
cp *.mp3 =1 # =1 is the first entry on the dirstack
po # returns you back to first placeThe other major time saver I use are sed and awk. I used each for a specific purpose. Sed works great for substitution, and awk I use to grab columns of data. Here's a sample of how I'd use both together. This will list the home directories of the users on a machine. It's simple, but there's a ton you can do with this technique.
who | awk '{print $1}' | sort | uniq | sed 's@^@/home/@g'
Here's other stuff I have grouped by sections in my
.cshrc First, I have my shell variables. The comments say what they do. The most important one is autolist.
set autolist # automatically lists possibilities after ambiguous completion
set dunique # removes duplicate entries in the dirstack
set fignore=(\~) # files ending in ~ will be ignored by completion
set histdup=prev # do not allow consecutive duplicate history entries
set noclobber # output redirection will not overwrite an existing file
set notify # notifies when a job completes
set symlinks=ignore # treats symbolic directories like real directories
set time=5 # processes that run longer than $time seconds will be timed.Second, bindkeys are pretty neat. I rebind the up and down arrow keys. By default they scroll up and down one at a time through the history. You can bind them to search the history based on what you've typed so far.
bindkey -k up history-search-backward # up arrow key
bindkey -k down history-search-forward # down arrow keyThird, completes allow for customizing tab completion. When I change directories, tab only completes directory names. This also works for aliases, sets, setenvs, etc.
complete cd 'p/1/d/'
complete alias 'p/1/a/'
complete setenv 'p/1/e/'
complete set 'p/1/s/'Fourth, I have all my aliases. I had to cut a bunch because of the lameness filter.
Re:pushd and popd (and other tricks) (Score:1)alias cwdcmd 'ls'
alias precmd 'echo -n "\033]0;$USER@`hostname` : $PWD\007"'
alias pd 'pushd'
alias po 'popd'
alias dirs 'dirs -v'
alias path 'printf "${PATH:as/:/\n/}\n"'
alias ff 'find . -name '\''\!:1'\'' rint \!:2*'
alias aw 'awk '\''{print $'\!:1'}'\'''
alias sub 'sed "s@"\!:1"@"\!:2"@g"'by MasterLock (581630) on Wednesday March 10, @03:23PM (#8524465)
Two of my most handy aliases (tcsh and 4DOS/4NT) are:
alias mcd 'md \!*; cd \!*'
alias rcd 'setenv OLD_DIR `pwd`;cd
Re:pushd and popd (and other tricks) (Score:1, Informative)..;echo $OLD_DIR;rd "$OLD_DIR"; unsetenv OLD_DIR' Usage: ~/> mcd junkDir ~/junk> -- do commands, unzip files, et cetera -- ~/junk> rcd ~/> -- back where you were and the dir is gone --
by Anonymous Coward on Wednesday March 10, @03:25PM (#8524497)alias pd pushd
alias po popd
cd/incredi/bly/long/path/name
pd/some/other/incredi/bly/long/path/name
cp *.mp3 =1 # =1 is the first entry on the dirstack
po # returns you back to first placecd
/some/directory/
cd/another/directory/
cp *.mp3 ~-
cd ~-
Re:pushd and popd (and other tricks) (Score:2, Informative) by MasterLock (581630) on Wednesday March 10, @03:33PM (#8524577)
f my most handy aliases (tcsh and 4DOS/4NT) are:
alias mcd 'md \!*; cd \!*'
alias rcd 'setenv OLD_DIR `pwd`; cd
..; echo $OLD_DIR;rd "$OLD_DIR"; unsetenv OLD_DIR' Usage:
~/> mcd junkDir
~/junk> -- do commands, unzip files, et cetera --
~/junk> rcd
~/> -- back where you were and the dir is gone --
Microsoft Windows XP - Popd
Popd
Changes the current directory to the directory stored by the pushd command.
Syntax
popd
Parameters
/? : Displays help at the command prompt.
Remarks
Every time you use the pushd command, a single directory is stored for your use. However, you can store multiple directories by using the pushd command multiple times.
The directories are stored sequentially in a virtual stack. If you use the pushd command once, the directory in which you use the command is placed at the bottom of the stack. If you use the command again, the second directory is placed on top of the first one. The process repeats every time you use the pushd command.
You can use the popd command to change the current directory to the directory most recently stored by the pushd command. If you use the popd command, the directory on the top of the stack is removed from the stack as the current directory is changed to that directory. If you use the popd command again, the next directory on the stack is removed.
When command extensions are enabled, the popd command removes any drive-letter assignations created by pushd.
Examples
You can use pushd and popd in a batch program to change the current directory from the one in which the batch program was run and then change it back. The following sample batch program shows how to do this:
@echo off rem This batch file deletes all .txt files in a specified directory pushd %1 del *.txt popd cls echo All text files deleted in the %1 directoryAn Introduction to the Z Shell - Directory Stacks
If you use csh, you may know about directory stacks. The pushd command puts the current directory on the stack, and changes to a new directory; the popd command pops a directory off the stack and changes to it.
phoenix% cd phoenix% PROMPT='Z %~> ' Z ~> pushd /tmp /tmp ~ Z /tmp> pushd /usr/etc /usr/etc /tmp ~ Z /usr/etc> pushd /usr/bin /usr/bin /usr/etc /tmp ~ Z /usr/bin> popd /usr/etc /tmp ~ Z /usr/etc> popd /tmp ~ Z /tmp> pushd /etc /etc /tmp ~ Z /etc> popd /tmp ~zsh's directory stack commands work similarly. One difference is the way pushd is handled if no arguments are given. As in csh, this exchanges the top two elements of the directory stack:
Z /tmp> dirs /tmp ~ Z /tmp> pushd ~ /tmpunless the stack only has one entry:
Z ~> popd /tmp Z /tmp> dirs /tmp Z /tmp> pushd ~ /tmpor unless the PUSHDTOHOME option is set:
Z ~> setopt pushdtohome Z ~> pushd ~ ~ /tmpAs an alternative to using directory stacks in this manner, we can get something like a directory history by setting a few more options and parameters:
~> DIRSTACKSIZE=8 ~> setopt autopushd pushdminus pushdsilent pushdtohome ~> alias dh='dirs -v' ~> cd /tmp /tmp> cd /usr /usr> cd bin /usr/bin> cd ../pub /usr/pub> dh 0 /usr/pub 1 /usr/bin 2 /usr 3 /tmp 4 ~ /usr/pub> cd -3 /tmp> dh 0 /tmp 1 /usr/pub 2 /usr/bin 3 /usr 4 ~ /tmp> ls =2/df /usr/bin/df /tmp> cd -4 ~>Note that =2 expanded to the second directory in the history list, and that cd -3 recalled the third directory in the list.
You may be wondering what all those options do. AUTOPUSHD made cd act like pushd. (alias cd=pushd is not sufficient, for various reasons.) PUSHDMINUS swapped the meaning of cd +1 and cd -1 we want them to mean the opposite of what they mean in csh, because it makes more sense in this scheme, and it's easier to type:
~> dh 0 ~ 1 /tmp 2 /usr/pub 3 /usr/bin 4 /usr ~> unsetopt pushdminus ~> cd +1 /tmp> dh 0 /tmp 1 ~ 2 /usr/pub 3 /usr/bin 4 /usr /tmp> cd +2 /usr/pub>PUSHDSILENT keeps the shell from printing the directory stack each time we do a cd, and PUSHDTOHOME we mentioned earlier:
/usr/pub> unsetopt pushdsilent /usr/pub> cd /etc /etc /usr/pub /tmp ~ /usr/bin /usr /etc> cd ~ /etc /usr/pub /tmp ~ /usr/bin /usr ~> unsetopt pushdtohome ~> cd /etc ~ /usr/pub /tmp ~ /usr/bin /usr /etc>DIRSTACKSIZE keeps the directory stack from getting too large, much like HISTSIZE:
/etc> setopt pushdsilent /etc> cd / /> cd / /> cd / /> cd / /> cd / /> cd / /> cd / /> cd / /> dh 0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 /Zsh offers a nice way to reference the directory stack quickly in your daily work. The description below is taken directly from the man page:A `~' followed by a number is replaced by the directory at that position in the directory stack. ~0 is equivalent to ~+, and ~1 is the top of the stack. ~+ followed by a number is replaced by the directory at that position in the directory stack. ~+0 is equivalent to ~+, and ~+1 is the top of the stack. ~- followed by a number is replaced by the directory that many positions from the bottom of the stack. ~-0 is the bottom of the stack. The PUSHD_MINUS option exchanges the effects of ~+ and ~- where they are followed by a number.dirs in Your Prompt: Better than $cwd
The C shell gives the absolute pathname of your current directory in $cwd (14.13). Many people use that in their prompts. If you use the pushd and popd (14.6) commands, you may not always remember exactly what's in your directory stack (I don't, at least). Also, do you want to shorten your home directory pathname to just a tilde (~) so it takes less room in the prompt? Here's how: run the dirs command and use its output in your prompt. A simple alias for cd users looks like this:
alias cd 'chdir \!* && set prompt="`dirs`% "'and the prompts look like:
/work/project % cd ~ % cd bin ~/bin %Here's what to put in .cshrc to make a multiline prompt (7.5) that shows the directory stack:
uname -n expr # PUT hostname.domain.name IN $hostname AND hostname IN $HOST: set hostname=`uname -n` setenv HOST `expr $hostname : '\([^.]*\).*'` alias setprompt 'set prompt="\\ ${USER}@${HOST} `dirs`\\ \! % "' alias cd 'chdir \!* && setprompt' alias pushd 'pushd \!* && setprompt' alias popd 'popd \!* && setprompt' setprompt # SET THE INITIAL PROMPTBecause bash can run a command each time it sets its prompt, and because it has built-in prompt operators (7.4), the bash version of all the stuff above fits on one line:
$(...) PS1='\n\u@\h $(dirs)\n\! \$ 'That makes a blank line before each prompt; if you don't want that, join the first and second lines of the setprompt alias or remove the first \n. Let's push a couple of directories and watch the prompt:
jerry@ora ~ 1 % pushd /work/src/perl /work/src/perl ~ jerry@ora /work/src/perl ~ 2 % cd ../cnews jerry@ora /work/src/cnews ~ 3 % pushd ~/bin ~/bin /work/src/cnews ~ jerry@ora ~/bin /work/src/cnews ~ 4 %
Of course, the prompt looks a little redundant there because each pushd command also shows the dirs output. A few commands later, though, having your directory stack in the prompt will be handy. If your directory stack has a lot of entries, the first line of the prompt can get wider than the screen. In that case, store the dirs output in a shell array (47.5) and edit it with a command like sed or with the built-in csh string editing (9.6).
For example, to show just the tail of each path in the dirs output, use the alias below; the C shell operator :gt globally edits all words, to the tail of each pathname:
alias setprompt 'set dirs=(`dirs`); set prompt="\\ ${USER}@${HOST} $dirs:gt\\ \! % "'Watch the prompt. If you forget what the names in the prompt mean, just type dirs:
History of visited directories in BASH LG #109 By Petar Marinov
Deficiencies of the CD command
Do you realize how many times you type cd per day? Do you realize how many times you retype the same directory names again and again? Ever since I migrated from 4DOS/NT shell on Windows to using Bash on Unix platforms, I've missed its cd history access. In 4DOS/NT the history of the visited directories can be navigated by Ctrl+PgUp/Dn. Every time you go to a new directory by cd, its name automatically goes on top of an easily accessible history list.
In Bash, cd - switches between the last two directories. This is a function in the right direction but many times I wanted to go to the directory before the last, I dreamed of something like cd -2.
A little scripting creates some sanity in the directory navigation of Bash.
Installing the CD history function
To install the modified CD function, copy acd_func.sh to any directory in your $PATH, or even your home directory. At the end of your .bashrc add source acd_func.sh. Restart your bash session and then type cd --.
lotzmana@safe$ cd -- 0 ~Type cd -- to verify if the installation works. Above you may see the result 0 ~. This shows that you have one directory in your history.
lotzmana@safe$ cd work lotzmana@safe$ cd scripts lotzmana@safe$ pwd /home/petarma/work/scripts lotzmana@safe$ cd -- 0 ~/work/scripts 1 ~/work 2 ~ lotzmana@safe$ cd -2 lotzmana@safe$ pwd /home/petarmaThe cd command works as usual. The new feature is the history of the last 10 directories and the cd command expanded to display and access it. cd -- (or simply pressing ctrl+w) shows the history. In front of every directory name you see a number. cd -num with the number you want jumps to the corresponding directory from the history.
How CD with history works
lotzmana@safe$ nl -w2 -s' ' acd_func.sh 1 # do ". acd_func.sh" 2 # acd_func 1.0.5, 10-nov-2004 3 # petar marinov, http:/geocities.com/h2428, this is public domain 4 cd_func () 5 { 6 local x2 the_new_dir adir index 7 local -i cnt 8 if [[ $1 == "--" ]]; then 9 dirs -v 10 return 0 11 fi 12 the_new_dir=$1 13 [[ -z $1 ]] && the_new_dir=$HOME 14 if [[ ${the_new_dir:0:1} == '-' ]]; then 15 # 16 # Extract dir N from dirs 17 index=${the_new_dir:1} 18 [[ -z $index ]] && index=1 19 adir=$(dirs +$index) 20 [[ -z $adir ]] && return 1 21 the_new_dir=$adir 22 fi 23 # 24 # '~' has to be substituted by ${HOME} 25 [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}" 26 # 27 # Now change to the new dir and add to the top of the stack 28 pushd "${the_new_dir}" > /dev/null 29 [[ $? -ne 0 ]] && return 1 30 the_new_dir=$(pwd) 31 # 32 # Trim down everything beyond 11th entry 33 popd -n +11 2>/dev/null 1>/dev/null 34 # 35 # Remove any other occurence of this dir, skipping the top of the stack 36 for ((cnt=1; cnt <= 10; cnt++)); do 37 x2=$(dirs +${cnt} 2>/dev/null) 38 [[ $? -ne 0 ]] && return 0 39 [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}" 40 if [[ "${x2}" == "${the_new_dir}" ]]; then 41 popd -n +$cnt 2>/dev/null 1>/dev/null 42 cnt=cnt-1 43 fi 44 done 45 return 0 46 } 47 alias cd=cd_func 48 if [[ $BASH_VERSION > "2.05a" ]]; then 49 # ctrl+w shows the menu 50 bind -x "\"\C-w\":cd_func -- ;" 51 fi4-7: cd_func() is a function, variables are declared local and are automatically deleted at the end of the function
8-11: if the function is called with a parameter "--" then it dumps the current content of the directory history. It is stored in the same place pushd/popd keep names -- the directory stack. Storage is the same, access is different.
12-13: Argument $1 is transferred into $the_new_dir for some postrocessing. Immediately after that, if there are no parameters we assume that user asked for his home directory.
14-22: If parameter begins with '-' then the user is attempting to access one of the names in the history list. $index gets the number of the directory, then we extract the corresponding name into $adir. For example, dirs +3 dumps directory #3 from the stack.
At this point in $the_new_dir we have either a name specified explicitly as a parameter or a name obtained from the history of previously visited directories.
23-25: If a directory name begins with '~' then this character has to be replaced by the actual home directory name.
26-30: pushd does the actual 'cd'. It also puts the name on top of the directory stack. stdout is redirected to /dev/null in order to completely imitate how 'cd' works. Notice that any output to stderr, for example a message telling that the directory specified by the user doesn't exist will show up, which is again similar to what 'cd' does. The function aborts if pushd fails. We also need the new directory name for further analysis and $the_new_dir carries it down the function.
31-33: Keeping track of more than 10 directories is unproductive. Since we have just pushed one on top of the stack, we trim off any that fall below 11 names deep.
34-44: We loop through all the names in the directory stack. Any name that matches the new current directory is eliminated. Again, we have to translate any name from the list which begins with '~' to its format of fully expanded home directory.
47: We assign cd to be cd_func().
48-51: If the bash version allows for macros to be assigned we make ctrl+w summon the history of visited directories.
This script defines a function. It must be sourced and not executed, so that cd_func() is parsed and stored in the current environment. Try env and you must see it after all environment variables.
Documentation page of the script
Visit the acd_func.sh man page.
Recommended Links
Google matched content
Softpanorama Recommended
Top articles
Sites
Please visit Heiner Steven SHELLdorado the best shell scripting site on the Internet
- Unix for Advanced Users - Navigating effectively - How do I remember where I was last
- Microsoft Windows XP - Popd
- An Introduction to the Z Shell - Directory Stacks
- dirs in Your Prompt: Better than $cwd
- History of visited directories in BASH LG #109 By Petar Marinov
- PushPop.vim - Pushdopd implementation for vim command-line vim online
- Hints and Musings
- When I googled for a Korn shell pushd, the closest thing I found was an illicit copy (gone, but cached) of part of an O'Reilly book on shell programming. And that version did not support directory names containing spaces. Here's my implementation: first, stack operators, then popd and pd (pushd is too much to type :-). This code will NOT work with a Bourne shell (it needs functions, typeset, and arrays to function in the Korn shell manner); and it will not work with bash - but bash already has pushd and popd.
Reference
dirs
dirs [+N | -N] [-clpv]Display the list of currently remembered directories. Directories are added to the list with the pushd command; the popd command removes directories from the list.
- +N
- Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
- -N
- Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
- -c
- Clears the directory stack by deleting all of the elements.
- -l
- Produces a longer listing; the default listing format uses a tilde to denote the home directory.
- Causes dirs to print the directory stack with one entry per line.
- -v
- Causes dirs to print the directory stack with one entry per line, prefixing each entry with its index in the stack.
popd
popd [+N | -N] [-n]Remove the top entry from the directory stack, and cd to the new top directory. When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs i.e., popd is equivalent to popd +0.
- +N
- Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.
- -N
- Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.
- -n
- Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.
pushd
pushd [dir | +N | -N] [-n]Save the current directory on the top of the directory stack and then cd to dir. With no arguments, pushd exchanges the top two directories.
- +N
- Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
- -N
- Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
- -n
- Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
- dir
- Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir'. cds to dir.
DIRSTACK
An array variable (see section Arrays) containing the current contents of the directory stack. Directories appear in the stack in the order they are displayed by the dirs built-in. Assigning to members of this array variable may be used to modify directories already in the stack, but the pushd and popd builtins must be used to add and remove directories. Assignment to this variable will not change the current directory. If DIRSTACK is unset, it loses its special properties, even if it is subsequently reset.
Etc
Society
Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers : Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism : The Iron Law of Oligarchy : Libertarian Philosophy
Quotes
War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda : SE quotes : Language Design and Programming Quotes : Random IT-related quotes : Somerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Bernard Shaw : Mark Twain Quotes
Bulletin:
Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 : Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law
History:
Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds : Larry Wall : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOS : Programming Languages History : PL/1 : Simula 67 : C : History of GCC development : Scripting Languages : Perl history : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history
Classic books:
The Peter Principle : Parkinson Law : 1984 : The Mythical Man-Month : How to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Haters Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite
Most popular humor pages:
Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor
The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D
Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...
You can use PayPal to to buy a cup of coffee for authors of this site Disclaimer:
The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.
Last modified: July 13, 2020