251 lines
14 KiB
HTML
Executable File
251 lines
14 KiB
HTML
Executable File
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="generator" content="pandoc">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||
<meta name="author" content="Dave Morriss">
|
||
<title>Some Bash tips (HPR Show 1843)</title>
|
||
<style type="text/css">code{white-space: pre;}</style>
|
||
<!--[if lt IE 9]>
|
||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||
<![endif]-->
|
||
<link rel="stylesheet" href="http://hackerpublicradio.org/css/hpr.css">
|
||
</head>
|
||
|
||
<body id="home">
|
||
<div id="container" class="shadow">
|
||
<header>
|
||
<h1 class="title">Some Bash tips (HPR Show 1843)</h1>
|
||
<h2 class="author">Dave Morriss</h2>
|
||
<hr/>
|
||
</header>
|
||
|
||
<main id="maincontent">
|
||
<article>
|
||
<header>
|
||
<h1>Table of Contents</h1>
|
||
<nav id="TOC">
|
||
<ul>
|
||
<li><a href="#introduction">Introduction</a><ul>
|
||
<li><a href="#basic-usage">Basic Usage</a><ul>
|
||
<li><a href="#pushd-dir">pushd <em>dir</em></a></li>
|
||
<li><a href="#popd">popd</a></li>
|
||
<li><a href="#dirs">dirs</a></li>
|
||
</ul></li>
|
||
<li><a href="#more-advanced-usage">More advanced usage</a><ul>
|
||
<li><a href="#pushd">pushd</a></li>
|
||
<li><a href="#popd-1">popd</a></li>
|
||
<li><a href="#dirs-1">dirs</a></li>
|
||
</ul></li>
|
||
</ul></li>
|
||
<li><a href="#conclusion">Conclusion</a></li>
|
||
<li><a href="#manual-pages">Manual Pages</a></li>
|
||
</ul>
|
||
</nav>
|
||
</header>
|
||
<h1 id="introduction">Introduction</h1>
|
||
<p>If you are a command-line user (and personally, I think you should be prepared to use the command line since it's so powerful) it's likely that you have used the <code>cd</code> command to change directory.</p>
|
||
<p>There are other directory movement commands within Bash: <code>pushd</code>, <code>popd</code> and <code>dirs</code>. I'm going to describe these today.</p>
|
||
<h2 id="basic-usage">Basic Usage</h2>
|
||
<h3 id="pushd-dir">pushd <em>dir</em></h3>
|
||
<p>This command changes directory like <code>cd</code> but it does more, it saves the previous directory, and the directory you've moved to, in a stack.</p>
|
||
<p>So, assume you have logged in and are in your home directory:</p>
|
||
<pre><code>dave@i7:~$ pwd
|
||
/home/dave
|
||
dave@i7:~$ pushd Documents
|
||
~/Documents ~
|
||
dave@i7:~/Documents$</code></pre>
|
||
<p><code>pwd</code> shows the directory I'm in. The <code>pushd Documents</code> takes me to my <code>Documents</code> directory. The stack is shown as a list, with the top of the stack on the left, and with <code>~</code> denoting the top-level home directory.</p>
|
||
<h3 id="popd">popd</h3>
|
||
<p>This command moves back to the previous directory. To be more precise, it takes the top-most (current) directory off the stack and changes directory to the new top.</p>
|
||
<p>So, continuing with the previous example:</p>
|
||
<pre><code>dave@i7:~/Documents$ popd
|
||
~
|
||
dave@i7:~$ pwd
|
||
/home/dave
|
||
dave@i7:~$</code></pre>
|
||
<p>So, <code>popd</code> has moved me back to the previous directory.</p>
|
||
<h3 id="dirs">dirs</h3>
|
||
<p>This command displays the directory stack. By default the stack is shown as a left-to-right list as we have seen in the above examples.</p>
|
||
<p>Using the <code>-v</code> option to <code>dirs</code> shows the stack as a vertical list with index numbers:</p>
|
||
<pre><code>dave@i7:~$ pushd Documents
|
||
~/Documents ~
|
||
dave@i7:~/Documents$ pushd subdir
|
||
~/Documents/subdir ~/Documents ~
|
||
dave@i7:~/Documents/subdir$ dirs -v
|
||
0 ~/Documents/subdir
|
||
1 ~/Documents
|
||
2 ~
|
||
dave@i7:~/Documents/subdir$</code></pre>
|
||
<p>Note that the directory stack is shown after each <code>pushd</code> but <code>dir -v</code> shows it vertically. The numbering begins with zero.</p>
|
||
<h2 id="more-advanced-usage">More advanced usage</h2>
|
||
<p>The three commands we have looked have a lot more features than we've seen so far.</p>
|
||
<h3 id="pushd">pushd</h3>
|
||
<p>A slightly modified version of the <code>pushd</code> manpage is available at the bottom of this document.</p>
|
||
<p>You can use <code>pushd</code> to add a directory to the stack without changing to that directory. To do this use the <code>-n</code> option:</p>
|
||
<pre><code>dave@i7:~$ pushd -n ~/Documents
|
||
~ ~/Documents
|
||
dave@i7:~$ pushd -n ~/Documents/subdir
|
||
~ ~/Documents/subdir ~/Documents
|
||
dave@i7:~$ dirs -v
|
||
0 ~
|
||
1 ~/Documents/subdir
|
||
2 ~/Documents</code></pre>
|
||
<p>Note that the order of the stack is not the same as it would have been if I had visited the directories in the same order.</p>
|
||
<p>You can manipulate the stack with <code>pushd</code> but the order is fixed, you can only rotate it (as if it's a loop) so that a particular directory is on top. This is done by using the option <code>+n</code> or <code>-n</code> (where <code>n</code> is an integer number not the letter 'n'). So <code>pushd +2</code> means to rotate the stack so that entry number 2 counting from the left (or as numbered by <code>dirs -v</code>) is raised to the top. Everything else rotates appropriately:</p>
|
||
<pre><code>dave@i7:~$ pushd +2
|
||
~/Documents ~ ~/Documents/subdir
|
||
dave@i7:~/Documents$ dirs -v
|
||
0 ~/Documents
|
||
1 ~
|
||
2 ~/Documents/subdir</code></pre>
|
||
<p>On the other hand <code>pushd -0</code> rotates the stack but numbers the elements from the right (not the same as <code>dirs -v</code>):</p>
|
||
<pre><code>dave@i7:~/Documents$ pushd -0
|
||
~/Documents/subdir ~/Documents ~
|
||
dave@i7:~/Documents/subdir$ dirs -p
|
||
~/Documents/subdir
|
||
~/Documents
|
||
~</code></pre>
|
||
<p>Element 0 was the directory <code>~/Documents/subdir</code> which is now at the top.</p>
|
||
<h3 id="popd-1">popd</h3>
|
||
<p>A slightly modified version of the <code>popd</code> manpage is available at the bottom of this document.</p>
|
||
<p>As with <code>pushd</code> <code>popd</code> also takes a <code>-n</code> option which manipulates the stack without changing the current directory.</p>
|
||
<pre><code>dave@i7:~$ pushd Documents/
|
||
~/Documents ~
|
||
dave@i7:~/Documents$ pushd subdir/
|
||
~/Documents/subdir ~/Documents ~
|
||
dave@i7:~/Documents/subdir$ popd -n
|
||
~/Documents/subdir ~
|
||
dave@i7:~/Documents/subdir$ popd
|
||
~
|
||
dave@i7:~$</code></pre>
|
||
<p>Note that <code>popd -n</code> removed element 1 from the stack whereas plain <code>popd</code> removed the zeroth element.</p>
|
||
<p>As with <code>pushd</code> options of the form <code>+n</code> and <code>-n</code> are catered for (where <code>n</code> is an integer number not the letter 'n'). In this case <code>popd +3</code> means to remove directory 3 from the stack, counting from the left, whereas <code>popd -2</code> counts from the right.</p>
|
||
<p>This is not stack rotation as with <code>pushd</code> but deletion of elements. If the topmost element is deleted then the current directory changes:</p>
|
||
<pre><code># Traverse several directories
|
||
dave@i7:~$ pushd Test1
|
||
~/Test1 ~
|
||
dave@i7:~/Test1$ pushd Test2
|
||
~/Test1/Test2 ~/Test1 ~
|
||
dave@i7:~/Test1/Test2$ pushd Test3
|
||
~/Test1/Test2/Test3 ~/Test1/Test2 ~/Test1 ~
|
||
dave@i7:~/Test1/Test2/Test3$ pushd Test4
|
||
~/Test1/Test2/Test3/Test4 ~/Test1/Test2/Test3 ~/Test1/Test2 ~/Test1 ~
|
||
dave@i7:~/.../Test2/Test3/Test4$ dirs -v
|
||
0 ~/Test1/Test2/Test3/Test4
|
||
1 ~/Test1/Test2/Test3
|
||
2 ~/Test1/Test2
|
||
3 ~/Test1
|
||
4 ~
|
||
# Now use popd +n to remove numbered directories
|
||
dave@i7:~/.../Test2/Test3/Test4$ popd +3
|
||
~/Test1/Test2/Test3/Test4 ~/Test1/Test2/Test3 ~/Test1/Test2 ~
|
||
dave@i7:~/.../Test2/Test3/Test4$ popd +0
|
||
~/Test1/Test2/Test3 ~/Test1/Test2 ~
|
||
dave@i7:~/Test1/Test2/Test3$ dirs -v
|
||
0 ~/Test1/Test2/Test3
|
||
1 ~/Test1/Test2
|
||
2 ~
|
||
# Then use popd -n to count from the bottom of the stack
|
||
dave@i7:~/Test1/Test2/Test3$ popd -1
|
||
~/Test1/Test2/Test3 ~
|
||
dave@i7:~/Test1/Test2/Test3$ dirs -v
|
||
0 ~/Test1/Test2/Test3
|
||
1 ~</code></pre>
|
||
<h3 id="dirs-1">dirs</h3>
|
||
<p>A slightly modified version of the <code>dirs</code> manpage is available below.</p>
|
||
<p>I have been using <code>dirs -v</code> to show the directory stack in what I think is a more readable form, but there are other options.</p>
|
||
<p>The <code>-p</code> option prints stack entries one per line without numbering. The <code>-l</code> option gives the full pathname without the tilde ('~') at the start denoting the home directory.</p>
|
||
<p>You can clear the entire directory stack using the <code>-c</code> option.</p>
|
||
<p>If you are thoroughly confused by the <code>+n</code> and <code>-n</code> options then using them with <code>dirs</code> makes it plainer what directories they refer to:</p>
|
||
<pre><code>dave@i7:~$ cd; pushd Test1; pushd Test2; pushd Test3; pushd Test4
|
||
~/Test1 ~
|
||
~/Test1/Test2 ~/Test1 ~
|
||
~/Test1/Test2/Test3 ~/Test1/Test2 ~/Test1 ~
|
||
~/Test1/Test2/Test3/Test4 ~/Test1/Test2/Test3 ~/Test1/Test2 ~/Test1 ~
|
||
|
||
dave@i7:~/.../Test2/Test3/Test4$ dirs +3
|
||
~/Test1
|
||
dave@i7:~/.../Test2/Test3/Test4$ dirs -v
|
||
0 ~/Test1/Test2/Test3/Test4
|
||
1 ~/Test1/Test2/Test3
|
||
2 ~/Test1/Test2
|
||
3 ~/Test1
|
||
4 ~
|
||
dave@i7:~/.../Test2/Test3/Test4$ dirs -3
|
||
~/Test1/Test2/Test3</code></pre>
|
||
<h1 id="conclusion">Conclusion</h1>
|
||
<p>What use are these commands?</p>
|
||
<p>I used to use them a lot pre-Linux when I was working on older Unix systems like Ultrix, SunOS and Solaris. This was in the days of real terminals and before the days of tabbed terminal emulators and virtual desktops.</p>
|
||
<p>I used to find it very helpful to be able to stop what I was doing in one directory and <code>pushd</code> to another to check something or answer a question, then <code>popd</code> back where I came from.</p>
|
||
<p>Nowadays I tend to have several terminal emulators on several virtual desktops and each has multiple tabs, so I use them to separate out my directories. However, if you tend to work in a single terminal session you might like I used to you might find them useful.</p>
|
||
<hr />
|
||
<h1 id="manual-pages">Manual Pages</h1>
|
||
<p><strong>pushd [-n] [+n] [-n]</strong></p>
|
||
<p><strong>pushd [-n] [dir]</strong></p>
|
||
<p>Adds a directory to the top of the directory stack, or rotates the stack, making the new top of the stack the current working directory. With no arguments, exchanges the top two directories and returns 0, unless the directory stack is empty. Arguments, if supplied, have the following meanings:</p>
|
||
<dl>
|
||
<dt><strong>-n</strong> (a hyphen and the letter 'n')</dt>
|
||
<dd>Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
|
||
</dd>
|
||
<dt><strong>+<em>n</em></strong> (a plus and an integer)</dt>
|
||
<dd>Rotates the stack so that the nth directory (counting from the left of the list shown by the <code>dirs</code> command, starting with zero) is at the top.
|
||
</dd>
|
||
<dt><strong>-<em>n</em></strong> (a hyphen and an integer)</dt>
|
||
<dd>Rotates the stack so that the nth directory (counting from the right of the list shown by the <code>dirs</code> command, starting with zero) is at the top.
|
||
</dd>
|
||
<dt><strong><em>dir</em></strong> (the name of a directory)</dt>
|
||
<dd>Adds the directory <em>dir</em> to the directory stack at the top, making it the new current working directory as if it had been supplied as the argument to the <code>cd</code> builtin.
|
||
</dd>
|
||
</dl>
|
||
<p>If the <code>pushd</code> command is successful, a <code>dirs</code> command is performed as well. If the first form is used, <code>pushd</code> returns 0 unless the <code>cd</code> to <em>dir</em> fails. With the second form, <code>pushd</code> returns 0 unless the directory stack is empty, a non-existent directory stack element is specified, or the directory change to the specified new current directory fails.</p>
|
||
<hr />
|
||
<p><strong>popd [-n] [+n] [-n]</strong></p>
|
||
<p>Removes entries from the directory stack. With no arguments, removes the top directory from the stack, and performs a cd to the new top directory. Arguments, if supplied, have the following meanings:</p>
|
||
<dl>
|
||
<dt><strong>-n</strong> (a hyphen and the letter 'n')</dt>
|
||
<dd>Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.
|
||
</dd>
|
||
<dt><strong>+<em>n</em></strong> (a plus and an integer)</dt>
|
||
<dd>Removes the nth entry counting from the left of the list shown by dirs, starting with zero. For example: <code>popd +0</code> removes the first directory, <code>popd +1</code> the second.
|
||
</dd>
|
||
<dt><strong>-<em>n</em></strong> (a hyphen and an integer)</dt>
|
||
<dd>Removes the nth entry counting from the right of the list shown by dirs, starting with zero. For example: <code>popd -0</code> removes the last directory, <code>popd -1</code> the next to last.
|
||
</dd>
|
||
</dl>
|
||
<p>If the <code>popd</code> command is successful, a <code>dirs</code> command is performed as well, and the return status is 0. <code>popd</code> returns false if an invalid option is encountered, the directory stack is empty, a non-existent directory stack entry is specified, or the directory change fails.</p>
|
||
<hr />
|
||
<p><strong>dirs [-clpv] [+n] [-n]</strong></p>
|
||
<p>Without options, displays the list of currently remembered directories. The default display is on a single line with directory names separated by spaces. Directories are added to the list with the pushd command; the popd command removes entries from the list.</p>
|
||
<dl>
|
||
<dt><strong>-c</strong></dt>
|
||
<dd>Clears the directory stack by deleting all of the entries.
|
||
</dd>
|
||
<dt><strong>-l</strong></dt>
|
||
<dd>Produces a listing using full pathnames; the default listing format uses a tilde to denote the home directory.
|
||
</dd>
|
||
<dt><strong>-p</strong></dt>
|
||
<dd>Print the directory stack with one entry per line.
|
||
</dd>
|
||
<dt><strong>-v</strong></dt>
|
||
<dd>Print the directory stack with one entry per line, prefixing each entry with its index in the stack.
|
||
</dd>
|
||
<dt><strong>+<em>n</em></strong> (a plus and an integer)</dt>
|
||
<dd>Displays the nth entry counting from the left of the list shown by dirs when invoked without options, starting with zero.
|
||
</dd>
|
||
<dt><strong>-<em>n</em></strong> (a hyphen and an integer)</dt>
|
||
<dd>Displays the nth entry counting from the right of the list shown by dirs when invoked without options, starting with zero.
|
||
</dd>
|
||
</dl>
|
||
<p>The return value is 0 unless an invalid option is supplied or n indexes beyond the end of the directory stack.</p>
|
||
<hr />
|
||
<!--
|
||
vim: syntax=markdown:ts=8:sw=4:ai:et:tw=78:fo=tcqn:fdm=marker
|
||
-->
|
||
</article>
|
||
</main>
|
||
</div>
|
||
</body>
|
||
</html>
|