<?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>Beyond Syntax &#187; bash</title>
	<atom:link href="http://www.beyond-syntax.com/category/bash/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.beyond-syntax.com</link>
	<description>Looking beyond syntactical meaning</description>
	<lastBuildDate>Thu, 01 Jul 2010 22:45:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Remote Instance of Firefox via SSH -X</title>
		<link>http://www.beyond-syntax.com/2009/07/remote-instance-of-firefox-via-ssh-x/</link>
		<comments>http://www.beyond-syntax.com/2009/07/remote-instance-of-firefox-via-ssh-x/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 18:46:57 +0000</pubDate>
		<dc:creator>Michael Schultz</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.beyond-syntax.com/?p=95</guid>
		<description><![CDATA[Firefox is a pretty decent web browser.  However, it can be a bit more clever than I want it at times.  For example, if I want to SSH into a remote machine and launch a instance of Firefox &#8212; to take on the remote machine&#8217;s IP address or access localhost &#8212; I would have to [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Read about the Firefox web browser" href="http://www.getfirefox.com/">Firefox</a> is a pretty decent web browser.  However, it can be a bit more clever than I want it at times.  For example, if I want to SSH into a remote machine and launch a instance of Firefox &#8212; to take on the remote machine&#8217;s IP address or access localhost &#8212; I would have to close the local instance then launch the remote instance.  That is annoying and unacceptable behaviour.</p>
<p>Luckily, the solution is fairly straightforward.  Once you have SSH&#8217;d into a remote host (using <code>ssh -X</code>), you simply need to run <code>firefox -no-remote</code>.  Of course you may want to tack on <code>&gt; /dev/null</code> and an ampersand <code>&amp;</code> to ignore the output and background the task. (Thanks to <a href="http://www.theopensourcerer.com/2007/11/15/remote-firefox-over-xssh/">The Open Sourcer</a>.)</p>
<p>With Firefox 2.x this behaviour was somewhat undocumented, but with Firefox 3.x, running <code>firefox --help</code> from the command line shows the <code>-no-remote</code> option.  It also seems that the default (i.e. <code>-remote</code>), is &#8220;documented&#8221; on Mozilla&#8217;s site for <a href="http://www.mozilla.org/unix/remote.html">Remote Control of UNIX Mozilla</a>.</p>
<p>If you wanted to make the <code>-no-remote</code> behaviour the default when SSH&#8217;d into remote machines, you could simply add a few lines to your bash profile to alias the <code>firefox</code> command.</p>
<pre># If we're forwarding X over SSH, make firefox execute on this machine
if [ -n "$SSH_CONNECTION" -a -n "$DISPLAY" ]; then
    alias firefox='firefox -no-remote'
fi</pre>
<p>At least that is what I did.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beyond-syntax.com/2009/07/remote-instance-of-firefox-via-ssh-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatic backups using cron and tar</title>
		<link>http://www.beyond-syntax.com/2007/10/automatic-backups-using-cron-and-tar/</link>
		<comments>http://www.beyond-syntax.com/2007/10/automatic-backups-using-cron-and-tar/#comments</comments>
		<pubDate>Sat, 06 Oct 2007 17:49:58 +0000</pubDate>
		<dc:creator>Michael Schultz</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://www.beyond-syntax.com/?p=47</guid>
		<description><![CDATA[This post is an import from a presentation I did in October of 2007.  Since I&#8217;ve made this presentation, I&#8217;ve stopped using my own script and suggest you use another tool for backups.  I hear rdiff-backup is good.  However, I believe this is still a good introduction to bash scripting, cron, and [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is an import from a presentation I did in October of 2007.  Since I&#8217;ve made this presentation, I&#8217;ve stopped using my own script and suggest you use another tool for backups.  I hear <a href="http://www.gnu.org/savannah-checkouts/non-gnu/rdiff-backup/">rdiff-backup</a> is good.  However, I believe this is still a good introduction to <code>bash</code> scripting, <code>cron</code>, and <code>tar</code>.</em></p>
<p><span id="more-47"></span></p>
<h3>Original Presentation</h3>
<p>Although it may be less useful without the accompanying speaker, the <a href="http://www.beyond-syntax.com/uploads/2009/02/backup.pdf">original presentation</a> is available.</p>
<h3>Source code for the shell script</h3>
<p>I have made the source code (<a href="http://www.beyond-syntax.com/uploads/2009/02/backup.sh">backup.sh</a>) available for download. In the top matter of the file describe how to add the script to your crontab.</p>
<h3>Description of the script</h3>
<p>For me, the best way to learn something is to take it line by line and that is what I&#8217;m going to do below. Naturally I will combine lines which are similar to save space. Since the target audience is someone who has never seen a shell script, some information may seem unimportant to you.</p>
<p>The concatenated source code that appears on this page may not agree with the source available for download. Odds are I decided the change was not worth updating this page, but made available for consumption as the script. If you notice something that is greatly different please contact me.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span></pre></div></div>

<p>Selection of a shell interpreter. This <em>must</em> be the first line in the file and be prefix with the &#8216;hash-bang&#8217; (or &#8217;sh-bang&#8217; for short).</p>
<p>I use <code>/bin/sh</code> since it seems to be the most universal amongst systems. It should be noted that on many systems <code>/bin/sh</code> is that same as <code>/bin/bash</code>, I do not know if this means the script will not work in <code>/bin/sh</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">SNAPDIR</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>snapshots<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span>
<span style="color: #007800;">RMT_DIR</span>=<span style="color: #ff0000;">&quot;user@hostname:~/snapshots&quot;</span>
<span style="color: #007800;">RMT_OPTIONS</span>=<span style="color: #ff0000;">&quot;-i <span style="color: #007800;">$HOME</span>/.ssh/id_dsa&quot;</span></pre></div></div>

<p>Setting some simple variables. Note that there are no spaces between the variable name, the equal sign, and the value; your script will not work with spaces between these three items.</p>
<p>Here I set the snapshot directory (where snapshots should be stored) to be <code>/var/snapshots/$USER</code>. <code>$USER</code> is a special variable that is the same as the user running the script.</p>
<p>Next are <code>RMT_DIR</code> and <code>RMT_OPTIONS</code> which are quoted. Quotes simply make sure spaces are included in the variable. Again, <code>$HOME</code> is a environmental variable that is always a user&#8217;s home directory.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">RMT_CMD</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">scp</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">DATE</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>Y<span style="color: #000000; font-weight: bold;">%</span>m<span style="color: #000000; font-weight: bold;">%</span>d<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">TAR</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">tar</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">MKDIR</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">CHMOD</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>This group of variables will run commands in a &#8220;sub-shell&#8221; before setting the variable name to the value. For example <code>$(which scp)</code> will execute <code>which scp</code> on the system and assign the value returned to <code>RMT_CMD</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">LAST_FULL</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">stat</span> <span style="color: #660033;">-f</span> <span style="color: #ff0000;">&quot;%Dc %Sc&quot;</span> <span style="color: #660033;">-t</span> <span style="color: #ff0000;">&quot;%Y%m%d&quot;</span> <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span>full-<span style="color: #000000; font-weight: bold;">*</span>.tar.gz \
            <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt; <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-n</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tail</span> -n1<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">LAST_TS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #800000;">${LAST_FULL}</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{ print $1}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">LAST_DATE</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #800000;">${LAST_FULL}</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{ print $2}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>In the final group of variables we use &#8220;pipes&#8221; which use the output of the first command as the input of the second command. For <code>LAST_FULL</code> we first <code>stat</code> files of the pattern &#8220;full-*.tar.gz&#8221; in the <code>${SNAPDIR}</code> directory. <em>(N.B. <code>${SNAPDIR}</code> dereferences the <code>SNAPDIR</code> variable we set earlier. The curly braces are not strictly necessary, however I use them when referring to local variables.)</em> For <code>stat</code> I am specifying that the output should be of the form &#8220;&lt;timestamp&gt; &lt;YYYYMMDD&gt;&#8221;, then <code>sort</code> the output using the number in the first column, and finally, take only the last file listed.</p>
<p>Once the last full snapshot time is known, we split it into two variables (<code>LAST_TS</code> and <code>LAST_DATE</code>), again using pipes and awk.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-d</span> <span style="color: #800000;">${SNAPDIR}</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #800000;">${MKDIR}</span> <span style="color: #800000;">${SNAPDIR}</span>
	<span style="color: #800000;">${CHMOD}</span> go-rwx <span style="color: #800000;">${SNAPDIR}</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>We&#8217;ll start by making sure the directory snapshots directory exists. If it doesn&#8217;t, make the directory and remove all permission from anyone not this user.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> incr <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #800000;">${TAR}</span> czf <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span>incr-<span style="color: #800000;">${DATE}</span>.tar.gz \
	       <span style="color: #660033;">--exclude-from</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>.snap-exclude \
	       <span style="color: #660033;">--listed-incremental</span>=<span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span>-<span style="color: #800000;">${LAST_DATE}</span>.snar \
	       <span style="color: #007800;">$HOME</span> <span style="color: #000000; font-weight: bold;">&amp;</span>lt; <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&amp;</span>lt; <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null
&nbsp;
	<span style="color: #800000;">${CHMOD}</span> go-rwx <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span>incr-<span style="color: #800000;">${DATE}</span>.tar.gz
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${RMT_CMD}</span>&quot;</span> <span style="color: #000000; font-weight: bold;">!</span>= <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #800000;">${RMT_CMD}</span> <span style="color: #800000;">${RMT_OPTIONS}</span> <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span>incr-<span style="color: #800000;">${DATE}</span>.tar.gz \
		       <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span>-<span style="color: #800000;">${LAST_DATE}</span>.snar \
		       <span style="color: #800000;">${RMT_DIR}</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>For creating an incremental backup. Using <code>tar</code>, <code>c</code>reate a g<code>z</code>ipped <code>f</code>ile at <code>${SNAPDIR}/incr-${DATE}.tar.gz</code>. Since you may not want <em>all</em> of your home directory backed up, you can exclude files listed in the <code>.snap-exclude</code> file. Now the most important part, <code>--listed-incremental</code>, tells <code>tar</code> what the timestamps of the files were last time it executed. If the timestamp on a file is newer than in the snar (&#8220;snapshort archive&#8221;), it will be added to the tarball. The last argument to tar is simply the directory to backup. <code>&gt;</code> and <code>2&gt;</code> redirect standard out and standard error to <code>/dev/null</code>, thus suppressing all output.</p>
<p>For the sake of security, we revoke all access from the file except for the current user.</p>
<p>The final step is to check of a <code>RMT_CMD</code> exists, if it does execute it. <code>scp</code> works well for this step, as would <code>rsync</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> full <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #800000;">${TAR}</span> czf <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span>full-<span style="color: #800000;">${DATE}</span>.tar.gz \
	       <span style="color: #660033;">--exclude-from</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>.snap-exclude \
	       <span style="color: #660033;">--listed-incremental</span>=<span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span>-<span style="color: #800000;">${DATE}</span>.snar \
	       <span style="color: #007800;">$HOME</span> <span style="color: #000000; font-weight: bold;">&amp;</span>lt; <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&amp;</span>lt; <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null
&nbsp;
	<span style="color: #800000;">${CHMOD}</span> go-rwx <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span>full-<span style="color: #800000;">${DATE}</span>.tar.gz
	<span style="color: #800000;">${CHMOD}</span> go-rwx <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span>-<span style="color: #800000;">${DATE}</span>.snar
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${RMT_CMD}</span>&quot;</span> <span style="color: #000000; font-weight: bold;">!</span>= <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #800000;">${CMT_CMD}</span> <span style="color: #800000;">${RMT_OPTIONS}</span> <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span>full-<span style="color: #800000;">${DATE}</span>.tar.gz \
		       <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span>-<span style="color: #800000;">${DATE}</span>.snar \
		       <span style="color: #800000;">${RMT_DIR}</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Creating a full backup is not much different than an incremental backup. The only difference is the <code>--listed-incremental</code> file (<code>tar</code> will create a new snapshot archive), thus starting with a fresh backup and timestamps. The reason for this is explained in the &#8220;Recovery&#8221; section.</p>
<p>The rest of the function is mostly the same as an incremental backup.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> normal <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #666666; font-style: italic;"># Make a full backup if no backup exists</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-f</span> <span style="color: #800000;">${SNAPDIR}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span>-<span style="color: #800000;">${LAST_DATE}</span>.snar <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
		full;
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #007800;">ELAPSED</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>s<span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #800000;">${LAST_TS}</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		<span style="color: #007800;">SNAP_FRAME</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">7</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000;">24</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000;">60</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000;">60</span> - <span style="color: #000000;">3600</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;"># Check if it has been over a week since a full snapshot</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #800000;">${ELAPSED}</span> <span style="color: #660033;">-gt</span> <span style="color: #800000;">${SNAP_FRAME}</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #666666; font-style: italic;"># make a full snapshot</span>
			full;
			<span style="color: #666666; font-style: italic;"># clean up files older than 4 weeks</span>
			clean;
		<span style="color: #000000; font-weight: bold;">else</span>
			incr;
		<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
		<span style="color: #7a0874; font-weight: bold;">unset</span> ELAPSED SNAP_FRAME
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Here we have the main &#8220;brain&#8221; of the program. It begins by making sure a backup exists, if one doesn&#8217;t the script makes a full backup. If at least one full backup exists, then we find out how long it has been since the last full backup and compare that to how frequently full backups should be made. <code>SNAP_FRAME</code> holds the frequency in which backups should be made (every 7 days * 24 hours / day * 60 minutes / hour * 60 seconds / minute (minus 1 hour for time delays)). If too much time has passed, create a full backup and clean out the old files. Otherwise just create an incremental backup.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> clean <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #c20cb9; font-weight: bold;">true</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>The script isn&#8217;t perfect. I have yet to determine a good way to clean out old files (one that isn&#8217;t tied to either <code>scp</code> or <code>rsync</code>).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> usage <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;usage: $0 [type]&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;[type] can be one of the following:&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;  normal - follow the daily incremental and weekly backup schedule&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;  incr   - create a incremental backup of <span style="color: #007800;">$HOME</span> to <span style="color: #007800;">${SNAPDIR}</span>&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;  full   - create a full backup of <span style="color: #007800;">$HOME</span> to <span style="color: #007800;">${SNAPDIR}</span>&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;  clean  - cleanup backups older than one month&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;  usage  - display this screen&quot;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;  --help - display this screen&quot;</span>
&nbsp;
	<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>This simple function displays the usage information if requested. <code>$0</code> is the script name as typed by the user.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
	<span style="color: #ff0000;">'normal'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		normal;
		<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #ff0000;">'incr'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		incr;
		<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #ff0000;">'full'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		full;
		<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #ff0000;">'clean'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		clean;
		<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #ff0000;">'--help'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		usage;
		<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #ff0000;">'usage'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		usage;
		<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		normal;
		<span style="color: #000000; font-weight: bold;">;;</span>
<span style="color: #000000; font-weight: bold;">esac</span></pre></div></div>

<p>Finally, the driver of the program, a case statement which reads the first argument (<code>$1</code>) and executes the desired function. The default operation is to run in normal mode, but the user is able to force an incremental update, full update, or clean out old files.</p>
<h3>Setting up a cronjob</h3>
<p><code>cron</code> is a simple utility that exists on almost all UNIX or UNIX-like systems. A daemon runs every minute to see if any user has a &#8220;cronjob&#8221; that needs to be executed, if a user does it will run it.</p>
<p>User level cronjobs are maintained by a program called <code>crontab</code>, to view your current crontab type: <code>crontab -l</code>, to edit your crontab use <code>crontab -e</code>.</p>
<p>I personally like to keep all my user level cronjobs in one place, <code>$HOME/.cronjobs/</code>. This folder conatins two files: <code>crontab</code> and <code>backup.sh</code>. <code>crontab</code> is a text file which hold what cronjobs I&#8217;d like to have run while <code>backup.sh</code> is the file described above.</p>
<p>My crontab files looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># User level crontab</span>
<span style="color: #666666; font-style: italic;"># min hr mday month wday command</span>
00    <span style="color: #000000;">13</span>  <span style="color: #000000; font-weight: bold;">*</span>    <span style="color: #000000; font-weight: bold;">*</span>     <span style="color: #000000; font-weight: bold;">*</span>    <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>directory<span style="color: #000000; font-weight: bold;">/</span>.cronjobs<span style="color: #000000; font-weight: bold;">/</span>backup.sh</pre></div></div>

<p>Which means I backup my files everyday at precisly 1:00pm by running the file located in <code>/path/to/home/directory/.cronjobs/backup.sh</code>. This can then be loaded into the system cronjobs using the following command.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">crontab <span style="color: #000000; font-weight: bold;">&amp;</span>lt; crontab</pre></div></div>

<h3>Recovering the data</h3>
<p>If you ever need to restore your backed up data all you need to do is find the most recent full backup (we&#8217;ll say <code>full-20071001.tar.gz</code>) and all the incremental backups since then (in our example <code>incr-2007100[2-5].tar.gz</code>). You&#8217;ll start by extracting the full backup to the correct folder via <code>tar xzf full-20071001.tar.gz</code>, followed by the incremental backups oldest to newest. Effectively you are restoring your entire home folder from n-days ago and applying the differences from each succeeding day. The commands should go as below (where <code>$</code> is the shell prompt).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xzf full-20071001.tar.gz
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xzf incr-20071002.tar.gz
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xzf incr-20071003.tar.gz
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xzf incr-20071004.tar.gz
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xzf incr-20071005.tar.gz</pre></div></div>

<p>After which you should have you home directory restored exactly as it appeared at 1:00pm on October 10, 2007.</p>
<p>Attachment: <a href="http://www.beyond-syntax.com/uploads/2009/02/backup.pdf">Automatic backups using <code>cron</code> and <code>tar</code></a> (PDF)<br />
Attachment: <a href="http://dev.beyond-syntax.com/scripts/backup.sh">backup.sh</a> (Shell script)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.beyond-syntax.com/2007/10/automatic-backups-using-cron-and-tar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
