<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Daily Build &#187; tools</title>
	<atom:link href="http://blog.bstpierre.org/category/tools/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.bstpierre.org</link>
	<description>Software Development, version 3.0</description>
	<lastBuildDate>Fri, 03 Feb 2012 02:59:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Change directories faster with zsh</title>
		<link>http://blog.bstpierre.org/save-three-keystrokes-with-zsh</link>
		<comments>http://blog.bstpierre.org/save-three-keystrokes-with-zsh#comments</comments>
		<pubDate>Mon, 25 Jul 2011 15:23:44 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[zsh]]></category>
		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=330</guid>
		<description><![CDATA[Something I didn&#8217;t know until recently: zsh does not require cd to change directories. Using the directory as a command implies &#8220;cd&#8221;. For example, instead of doing: me@server:/home/me $ cd /tmp me@server:/tmp $ You can just do: me@server:/home/me $ /tmp me@server:/tmp $ That&#8217;s three whole keystrokes (nearly half the command shown above), all day long.]]></description>
			<content:encoded><![CDATA[<p>Something I didn&#8217;t know until recently:</p>
<blockquote><p>zsh does not require <code>cd </code> to change directories.</p></blockquote>
<p>Using the directory as a command implies &#8220;cd&#8221;. For example, instead of doing:</p>
<pre>
me@server:/home/me $ cd /tmp
me@server:/tmp $
</pre>
<p>You can just do:</p>
<pre>
me@server:/home/me $ /tmp
me@server:/tmp $
</pre>
<p>That&#8217;s three whole keystrokes (nearly half the command shown above), all day long.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/save-three-keystrokes-with-zsh/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making perl unit tests easier to run in emacs</title>
		<link>http://blog.bstpierre.org/perl-unit-tests-easier-in-emacs</link>
		<comments>http://blog.bstpierre.org/perl-unit-tests-easier-in-emacs#comments</comments>
		<pubDate>Fri, 08 Jul 2011 00:57:15 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[unit-test]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=314</guid>
		<description><![CDATA[It&#8217;s a hassle to have to switch from emacs to the shell, run unit tests, pick out the failure, switch back to emacs, navigate to the line, forget where you were supposed to go, switch back, etc etc. The whole process is much easier with compilation-perl.el. This handy bit of code sets up patterns for [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a hassle to have to switch from emacs to the shell, run unit tests, pick out the failure, switch back to emacs, navigate to the line, forget where you were supposed to go, switch back, etc etc.</p>
<p>The whole process is much easier with <a title="compilation-perl.el" href="http://user42.tuxfamily.org/compilation-perl/index.html">compilation-perl.el</a>. This handy bit of code sets up patterns for compilation-mode so that test failures (among other things) are recognized. Just add compilation-perl.el to your emacs lisp directory and follow the directions at the top of the file for installation instructions.</p>
<p>So my test process is now:</p>
<ol>
<li>Hit <code>F4</code> (which I have mapped to <code>compile</code>).</li>
<li>If necessary, change the command to either <code>make test</code> or to run a specific test I&#8217;m working on (e.g. <code>perl t/MyModule.t</code>).</li>
<li>If there&#8217;s a failure, press <code>C-F4</code> (which I have mapped to <code>next-error</code>) and it brings me right to the failure.</li>
<li>Repeat from step 1 (but the second time around I don&#8217;t need to do step 2 since the command is already set properly).</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/perl-unit-tests-easier-in-emacs/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Lenny to Build Jaunty Packages</title>
		<link>http://blog.bstpierre.org/lenny-jaunty-packages</link>
		<comments>http://blog.bstpierre.org/lenny-jaunty-packages#comments</comments>
		<pubDate>Thu, 13 May 2010 15:43:13 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=296</guid>
		<description><![CDATA[&#60;shameless_plug&#62; I&#8217;m in the middle of putting together packages for the analog call generator my startup is building. &#60;/shameless_plug&#62; The process for building debian packages is actually very well documented, though many of the tutorials you will find are aimed at people who are packaging third-party software instead of their own. Also, I&#8217;m running on [...]]]></description>
			<content:encoded><![CDATA[<p>&lt;shameless_plug&gt;<br />
I&#8217;m in the middle of putting together packages for the <a title="RCG-4001 Analog Call Generator" href="http://rimaytech.com/rcg-4001/">analog call generator</a> my <a href="http://rimaytech.com/">startup</a> is building.<br />
&lt;/shameless_plug&gt;</p>
<p>The process for building debian packages is actually very well documented, though many of the tutorials you will find are aimed at people who are packaging third-party software instead of their own.</p>
<p>Also, I&#8217;m running on Debian&#8217;s Lenny, and I need to produce packages that install cleanly on Ubuntu&#8217;s Jaunty Jackalope. It sounds worse than it is.</p>
<p>Take this with a grain of salt &#8212; it works for me, but I&#8217;m certainly not an expert in this area.</p>
<p>Steps:</p>
<ol>
<li>Debianize each package. (<a title="How to Package for Debian" href="http://wiki.debian.org/HowToPackageForDebian">Here&#8217;s an excellent quick &amp; dirty guide to getting a package created.</a>)</li>
<li>Build the packages: <code>(cd MYPROJECT; fakeroot ./debian/rules binary)</code>. Don&#8217;t distribute these packages, they are probably wrong! But this is the quickest way to get everything mostly-working.</li>
<li>Sanity check the packages: <code>dpkg-deb -c MYPROJECT.deb; dpkg-deb -I MYPROJECT.deb; dpkg -i MYPROJECT.deb<br />
</code></li>
<li>Check in your MYPROJECT/debian/ directory to source control (e.g. git, svn, etc).</li>
<li>This is the tricky step, and one that I didn&#8217;t see explicitly documented.You need a version of debootstrap that knows about ubuntu distributions. (Ubuntu debootstrap knows about Debian, but not the other way around.)
<ol>
<li>Download the jaunty (or whatever ubuntu version) <a href="http://packages.ubuntu.com/jaunty-backports/admin/debootstrap">debootstrap source package</a>. Grab the .dsc and .tar.gz from that page.</li>
<li>Run <code>dpkg-source -x debootstrap_1.0.20~jaunty1.dsc</code> &#8212; this extracts the source.</li>
<li><code>(cd debootstrap-1.0.20~jaunty1; debuild -uc -us)</code> &#8212; this will build a .deb you can install on your lenny machine. Install package &#8220;devscripts&#8221; if you don&#8217;t have debuild.</li>
<li><code>sudo dpkg -i debootstrap_1.0.20~jaunty1_all.deb</code></li>
</ol>
</li>
<li>Install pbuilder. This will help you build the packages in a clean chroot &#8212; i.e. without all the pollution you have on your machine that could be making the packages work even though they will break on your users&#8217; machines.</li>
<li>Put the <a href="http://wiki.rabbitvcs.org/wiki/development/pbuilder">code found here</a> in your ~/.pbuilderrc.</li>
<li>Apply <a href="http://wiki.debian.org/PbuilderTricks#Howtobuildfordifferentdistributions">this sudoers change</a> (optional but convenient).</li>
<li><code>sudo DIST=jaunty pbuilder create</code> &#8230; then wait. (If you have lame internet service (Hughes) and a daily bandwidth cap, you may want to schedule this for the free-for-all period: <code>echo sudo DIST=jaunty pbuilder create | at 2:30am tomorrow</code>)</li>
</ol>
<p>If you see anything I&#8217;m missing or would like to add, please drop a comment below. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/lenny-jaunty-packages/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>zsh history expansion</title>
		<link>http://blog.bstpierre.org/zsh-history-expansion</link>
		<comments>http://blog.bstpierre.org/zsh-history-expansion#comments</comments>
		<pubDate>Mon, 15 Feb 2010 13:59:52 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[zsh]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=269</guid>
		<description><![CDATA[Exploring zsh features made me want to figure out some of the history-editing wizardry. (Bash has similar history tricks, I just never bothered to dive too deeply into them.) If you want to experiment with history expansion a bit, you can echo the result instead of executing it: hostname:~/dir% ls /some/long/path/to/file_0.1-2_i386.changes hostname:~/dir% echo !?ls?:s/-2/-3/ echo [...]]]></description>
			<content:encoded><![CDATA[<p>Exploring zsh features made me want to figure out some of the history-editing wizardry. (Bash has similar history tricks, I just never bothered to dive too deeply into them.)</p>
<p>If you want to experiment with history expansion a bit, you can echo the result instead of executing it:</p>
<pre>hostname:~/dir% ls /some/long/path/to/file_0.1-2_i386.changes
hostname:~/dir% echo !?ls?:s/-2/-3/
echo ls /some/long/path/to/file_0.1-3_i386.changes</pre>
<p>In this case, what I wanted to do is repeat a long command that referenced a file with a version number in it &#8212; but I wanted to use a different version number (-3 instead of the previously given version -2).</p>
<p>History expansion uses &#8220;!&#8221; (&#8220;bang&#8221;, or exclamation point). If you want to select the previous command to expand based on a string match, &#8220;!?str&#8221; will find the previous command that contains &#8220;str&#8221;. If you want to substitute some part of that previous command, put another question mark on the end, add a colon, and use the the &#8220;s&#8221; modifier. In the example above, &#8220;!?ls?&#8221; means expand the previous command containing &#8220;ls&#8221;. The &#8220;:s/-2/-3/&#8221; means modify that expanded command to replace the occurrence of &#8220;-2&#8243; with &#8220;-3&#8243;.</p>
<p>(Of course, to actually get all of that figured out and working, I had to iterate the sequence of commands above about a dozen times.)</p>
<p>Leave a comment with your favorite zsh history trick. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/zsh-history-expansion/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Set Your zsh Prompt</title>
		<link>http://blog.bstpierre.org/zsh-prompt</link>
		<comments>http://blog.bstpierre.org/zsh-prompt#comments</comments>
		<pubDate>Mon, 01 Feb 2010 16:05:13 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[zsh]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=264</guid>
		<description><![CDATA[Since the beginning of time, all the cool kids have had really cool shell prompts. It's a great place to display helpful information, and zsh has features that let you have a flexible, informative, unobtrusive prompt.]]></description>
			<content:encoded><![CDATA[<p>Since the beginning of time, all the cool kids have had really cool shell prompts. It&#8217;s a great place to display helpful information, and zsh has features that let you have a flexible, informative, unobtrusive prompt.</p>
<p>Set your prompt by setting <code>$PROMPT</code>. If you do <code>PROMPT='foo '</code>, the shell will give you a <code>foo </code> prompt for every command. Not terribly useful but you get the point.</p>
<p>There are a bunch of codes you can use in the value of PROMPT to get useful output. For example, %m gives the name of the machine you&#8217;re running on, and %~ gives the name of the current working directory. For a list of all the codes, check the &#8220;<a title="man page for zshmisc" href="http://www.manpagez.com/man/1/zshmisc/">zshmisc</a>&#8221; man page under the section &#8220;SIMPLE PROMPT ESCAPES&#8221;. Note that there are codes for boldface, underline, and colors here too.</p>
<p>The drawback to having all kinds of information in your prompt is that you limit the length of commands that you can enter without scrolling. Scrolling stinks because the command is harder to read. Enter the &#8220;right prompt&#8221;. Set RPS1 to contain the lengthy part of your prompt, and it will be displayed on the right margin of your terminal. Then when commands get long and encroach on the right prompt, it will conveniently disappear. Read Quentin&#8217;s comment on <a href="http://who-t.blogspot.com/2009/08/case-for-zsh.html?showComment=1253567443515#c3597222540288946216">this zsh post</a>.</p>
<p>Here&#8217;s a gotcha with RPS1 and fancy prompt formatting: gnome-terminal does not behave well when these are set. I&#8217;m trying out alternatives to see which will be better.</p>
<p>Lastly, a trick I picked up from <a href="http://justinchouinard.com/">Justin</a>. Zsh provides hooks that you can use to do things before and after a command runs. Just define the functions preexec and precmd. This example sets the title of the xterm while a command is running:</p>
<pre>function title() {
    # escape '%' chars in $1, make nonprintables visible
    local a=${(V)1//\%/\%\%}

    # Truncate command, and join lines.
    a=$(print -Pn "%40&gt;...&gt;$a" | tr -d "\n")

    case $TERM in
        screen*)
            print -Pn "\e]2;$a @ $2\a" # plain xterm title
            print -Pn "\ek$a\e\\"      # screen title (in ^A")
            print -Pn "\e_$2   \e\\"   # screen location
            ;;
        xterm*)
            print -Pn "\e]2;$a @ $2\a" # plain xterm title
            ;;
    esac
}

# precmd is called just before the prompt is printed
function precmd() {
    title "zsh" "%m:%55&lt;...&lt;%~"
}

# preexec is called just before any command line is executed
function preexec() {
    title "$1" "%m:%35&lt;...&lt;%~"
}</pre>
<p><b>Update</b>: Set variable a to local in function title above as suggested in the comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/zsh-prompt/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Make the zsh zle handle &#8220;words&#8221; correctly</title>
		<link>http://blog.bstpierre.org/zsh-zle-words</link>
		<comments>http://blog.bstpierre.org/zsh-zle-words#comments</comments>
		<pubDate>Wed, 27 Jan 2010 15:40:18 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[zsh]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=272</guid>
		<description><![CDATA[Snippet from my .zshrc: # This controls what the line editor considers a word. By default it # includes '/', which makes it so that when I M-del (attempting to erase # a directory in a path), I erase the whole path. Annoying. # WORDCHARS='*?_-.[]~=/&#38;;!#$%^(){}&#60;&#62;' # (default) WORDCHARS='*?_-.[]~=&#38;;!#$%^(){}&#60;&#62;' After living with this for a while, [...]]]></description>
			<content:encoded><![CDATA[<p>Snippet from my .zshrc:</p>
<p><code># This controls what the line editor considers a word. By default it<br />
# includes '/', which makes it so that when I M-del (attempting to erase<br />
# a directory in a path), I erase the whole path. Annoying.<br />
# WORDCHARS='*?_-.[]~=/&amp;;!#$%^(){}&lt;&gt;' # (default)<br />
WORDCHARS='*?_-.[]~=&amp;;!#$%^(){}&lt;&gt;'<br />
</code></p>
<p>After living with this for a while, I realize that I should probably remove the underscore too, since that&#8217;s what I was used to in bash.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/zsh-zle-words/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving to zsh</title>
		<link>http://blog.bstpierre.org/moving-to-zsh</link>
		<comments>http://blog.bstpierre.org/moving-to-zsh#comments</comments>
		<pubDate>Mon, 25 Jan 2010 15:20:27 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[zsh]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=258</guid>
		<description><![CDATA[To get started: sudo aptitude install zsh chsh /bin/zsh That&#8217;s pretty simple. Of course, you&#8217;re not running zsh yet&#8230; either logout and log back in or just run zsh at the prompt. You&#8217;ll get a series of prompts to configure a .zshrc. It only takes a few minutes, so run through the options and save [...]]]></description>
			<content:encoded><![CDATA[<p>To get started:</p>
<ol>
<li>sudo aptitude install zsh</li>
<li>chsh /bin/zsh</li>
</ol>
<p>That&#8217;s pretty simple.</p>
<p>Of course, you&#8217;re not <em>running</em> zsh yet&#8230; either logout and log back in or just run zsh at the prompt. You&#8217;ll get a series of prompts to configure a .zshrc. It only takes a few minutes, so run through the options and save the file.</p>
<p>Next up: setting a custom prompt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/moving-to-zsh/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>9 &#8220;Must-Have&#8221; Tools for Software Teams</title>
		<link>http://blog.bstpierre.org/must-have-tools-software-teams</link>
		<comments>http://blog.bstpierre.org/must-have-tools-software-teams#comments</comments>
		<pubDate>Mon, 18 Jan 2010 16:06:38 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[tools]]></category>
		<category><![CDATA[software-engineering]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=254</guid>
		<description><![CDATA[The items below are useful systems based on my experience working with a bunch of different software teams at a handful of companies over the past decade-plus. I haven&#8217;t bothered to list things like compilers, interpreters, libraries, etc. If you don&#8217;t have those, you aren&#8217;t making software&#8230; Source control. This almost belongs in the &#8220;if [...]]]></description>
			<content:encoded><![CDATA[<p>The items below are useful systems based on my experience working with a bunch of different software teams at a handful of companies over the past decade-plus. I haven&#8217;t bothered to list things like compilers, interpreters, libraries, etc. If you don&#8217;t have those, you aren&#8217;t making software&#8230;</p>
<ol>
<li><strong>Source control.</strong> This almost belongs in the &#8220;if you don&#8217;t have it, you aren&#8217;t making software&#8221; category. There are so many free and simple to use tools that it is ridiculous to not use source control. Pick one of: subversion, git, or any of the dozens of other free tools and use it. I guess I&#8217;d say &#8220;if you don&#8217;t have it, you are making a mess&#8221;.</li>
<li><strong>Bug/issue tracker</strong>. Trac is a decent tool for keeping tabs on development tasks and bugs. Bugzilla is ok too. If you have a budget, there is an apparently infinite set of commercial systems available of varying quality. Almost anything is better than a list of scribbles on your whiteboard.</li>
<li><strong>Backup server.</strong> You <em>can</em> do software without it, but the odds are against you lasting long.</li>
<li><strong>Build system.</strong> Automated nightly/continuous builds are awesome. Whether you DIY, install something free like hudson, or purchase a commercial system, this is a key piece of making sure that the software maintains at least a minimum level of quality (i.e. it is always buildable). After having worked on a couple of teams that didn&#8217;t have such a system, and the build was always broken, I would never work without it again.</li>
<li><strong>IM / Jabber</strong>. Especially with a conference server where the rooms are archived and available via the web. Searchable is nice, but making them available where they can be grepped isn&#8217;t bad either. I didn&#8217;t become convinced of the value here until last summer.It sounds like an extra distraction and sometimes it can be, but you can turn it off when you&#8217;re heads-down coding. And it has the potential to <em>reduce</em> the number of interruptions from people walking into your office with questions that could have been answered in an IM. It&#8217;s lighter weight than email and rooms are broadcast by nature so you don&#8217;t have to spam a huge list of people to find the answer you&#8217;re looking for.</li>
<li><strong>Email lists</strong>. Must have web-browsable archives; the list without this has much less value. Search would be a nice bonus, though I haven&#8217;t seen it done well. This lets teams communicate a bit more formally than IM and provides a record of certain discussions and decisions.</li>
<li><strong>FTP server.</strong> Bonus points for a TFTP server. Maybe it&#8217;s because of the nature of embedded software, but every team I&#8217;ve been on has always had to fling around large files and images. Email is horribly inefficient for this. Also, most of the products I&#8217;ve worked on needed an FTP (or TFTP) server to boot from. You&#8217;re likely to install something on your development machine, which is fine, but it&#8217;s convenient to have a central team/company internal server so you can just tell someone that a file is in your public directory on &#8220;the ftp server&#8221;. Microsoft shops and folks that don&#8217;t need to boot via FTP can probably get away with samba shares.</li>
<li><strong>Doc server.</strong> Wiki is probably the best way to go if your team doesn&#8217;t <em>have</em> to produce overly-formal documentation. Wikis and formal document control systems that I&#8217;ve used have had horrible search, which sucks but I haven&#8217;t found a great solution. In the past I&#8217;ve done this with a combination of a formal doc tool plus a blog for the informal &#8220;howto&#8221; kind of notes that are always needed.</li>
<li><strong>Code review.</strong> I can&#8217;t say I&#8217;ve worked anywhere that had a dedicated code review tool. However, when all of the development machines are on NFS so that everyone has a view of your workspace, IM fits the bill reasonably well: post a review request to the chat room with the path to your changes and get an ad hoc on the spot code review. With some discipline and a supportive culture this works very smoothly. (This arrangement could probably be done with an internal pastebin, which I haven&#8217;t listed here as must-have since I haven&#8217;t really seen it used.)</li>
</ol>
<p>What would you add to this list? Any other tools or systems that, if missing, would make you think twice about taking a job?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/must-have-tools-software-teams/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Use SSH to Forward Multiple Protocols to Multiple Machines</title>
		<link>http://blog.bstpierre.org/ssh-forward-multiple-protocols-to-multiple-machines</link>
		<comments>http://blog.bstpierre.org/ssh-forward-multiple-protocols-to-multiple-machines#comments</comments>
		<pubDate>Fri, 04 Dec 2009 16:03:33 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[ssh]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=239</guid>
		<description><![CDATA[Let's say you have a half-dozen machines at work you want to log into. Instead of setting up a remote forwarding connection from each of those machines, you can have the connection from your main machine perform multiple forwardings instead of just one. This even works if some of the machines don't support ssh.]]></description>
			<content:encoded><![CDATA[<p><em>(This is part five in a <a href="../category/tools/ssh">series of posts on ssh</a>.)</em></p>
<p>Let&#8217;s say you have a half-dozen machines at work you want to log into. Instead of setting up a <a href="http://blog.bstpierre.org/ssh-remote-port-forwarding-tunnels">remote forwarding connection</a> from each of those machines, you can have the connection from your main machine perform multiple forwardings instead of just one. This even works if some of the machines don&#8217;t support ssh.</p>
<p>It shouldn&#8217;t surprise you at this point that you can do this with your config file. On your work machine, you might have something like:</p>
<pre>Host tunnel
  HostName cloud.example.com
  User mycloudusername
  IdentityFile ~/.ssh/id_dsa
  Port 22
  RSAAuthentication yes
  PubkeyAuthentication yes
  ExitOnForwardFailure yes
  # tunnel ssh to myworkmachine
  RemoteForward 4022 localhost:22
  # tunnel remote desktop to mywindowsbox via myworkmachine
  RemoteForward 5389 192.168.4.10:3389
  # tunnel http to mywindowsbox via myworkmachine
  RemoteForward 5080 192.168.4.10:80
  # tunnel remote desktop to otherwindowsbox via myworkmachine
  RemoteForward 6389 192.168.4.11:3389
  # tunnel ssh to workserver via myworkmachine
  RemoteForward 7022 192.168.4.2:22</pre>
<p>You can add a bunch of forwardings as shown above. Each entry will open the given port on cloud and forward it to the specified port on the specified machine. Now when you run &#8220;ssh tunnel&#8221; on your work machine, it will connect to cloud and set up the five port forwardings specified in your config file.</p>
<p>Then when logged in to cloud.example.com, you can do, for example, &#8220;ssh -p 7022 myserverlogin@localhost&#8221; to log into the machine called workserver.</p>
<p>If you mirror the remote forwardings in your home config file as local forwardings, then when you &#8220;ssh work&#8221; from home you can remote desktop to a windows machine from your home pc by doing &#8220;rdesktop -u myworkwinuser localhost:5389&#8243; and it will use the tunnel. (The connection will go from your home pc to cloud, to myworkmachine, to mywindowsbox.) The windows machine does not need to know anything about ssh.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/ssh-forward-multiple-protocols-to-multiple-machines/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open an SSH Tunnel in Four Seconds or Less</title>
		<link>http://blog.bstpierre.org/open-an-ssh-tunnel-in-four-seconds-or-less</link>
		<comments>http://blog.bstpierre.org/open-an-ssh-tunnel-in-four-seconds-or-less#comments</comments>
		<pubDate>Thu, 03 Dec 2009 15:28:47 +0000</pubDate>
		<dc:creator>Brian St. Pierre</dc:creator>
				<category><![CDATA[ssh]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.bstpierre.org/?p=233</guid>
		<description><![CDATA[As I mentioned in a previous post on ssh configuration, your config file can specify a variety settings for each server. In fact, the Hosts you use don't even have to exist! Consider the following snippet in your ~/.ssh/config.]]></description>
			<content:encoded><![CDATA[<p><em>(This is part four in a <a href="../category/tools/ssh">series of posts on ssh</a>.)</em></p>
<p>As I mentioned in a previous post on <a href="http://blog.bstpierre.org/configure-ssh-username">ssh configuration</a>, your config file can specify a variety settings for each server.</p>
<p>In fact, the Hosts you use don&#8217;t even have to exist! (The HostName is the important part.) Consider the following snippet in your ~/.ssh/config.</p>
<pre>#
Host work
  HostName localhost
  User myworklogin
  IdentityFile ~/.ssh/id_dsa
  Port 4022
  RSAAuthentication yes
  PubkeyAuthentication yes
  LocalForward 4022 localhost:4022</pre>
<p>I&#8217;m going to assume remote forwarding is set up and the connection is open from work to cloud as described in <a href="http://blog.bstpierre.org/ssh-remote-port-forwarding-tunnels">this post on remote forwarding</a>; and you&#8217;ve got local forwarding set up from home to cloud as described in this post on <a href="http://blog.bstpierre.org/local-ssh-forwarding">local port forwarding</a>.</p>
<p>Now you can do &#8220;ssh work&#8221; from your home pc, and it will automatically log you into your work pc with the right credentials using the tunnel on cloud.example.com. And the scp example above simplifies to &#8220;scp work:/tmp/foo.txt ~/foo.txt&#8221; &#8212; you don&#8217;t have to remember the forwarded port numbers.</p>
<p>Typing &#8220;ssh work&#8221; is nine keystrokes (eight letters plus enter). If you can type 40 wpm, that&#8217;s 200 keystrokes per minute, or 3.33 keystrokes per second, which means you can open the tunnel in four seconds!</p>
<p>If you add &#8220;alias ssw=&#8217;ssh work&#8217;&#8221; to your ~/.bashrc, you&#8217;re down to four keystrokes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bstpierre.org/open-an-ssh-tunnel-in-four-seconds-or-less/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

