<?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>Edward A. Webb (.com) &#187; linux</title>
	<atom:link href="http://www.edwardawebb.com/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.edwardawebb.com</link>
	<description>get all his digital goodness 24/7</description>
	<lastBuildDate>Mon, 07 May 2012 12:58:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Linux Turns 20!</title>
		<link>http://www.edwardawebb.com/site-news/linux-turns-20</link>
		<comments>http://www.edwardawebb.com/site-news/linux-turns-20#comments</comments>
		<pubDate>Tue, 12 Apr 2011 21:22:46 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[Site News]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=922</guid>
		<description><![CDATA[I was only 6 when Linus shared his first offering to the world, but I do remember the linux superbowl ad by IBM.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.linuxfoundation.org/20th" rel="nofollow"  target="_blank"><img src="http://www.linuxfoundation.org/20th/images/lf_linux20_webbadge.png" width="300" height="250" alt="lf linux20 webbadge Linux Turns 20!" border="0" title="Linux Turns 20!" /></a></p>
<p>
I was only 6 when Linus shared his first offering to the world, but I do remember the <a href="http://www.youtube.com/watch?v=sYT5VcPSjSg" rel="nofollow" >linux superbowl ad by IBM</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/site-news/linux-turns-20/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting IP addresses for remote nodes</title>
		<link>http://www.edwardawebb.com/linux/ip-addresses-remote-nodes</link>
		<comments>http://www.edwardawebb.com/linux/ip-addresses-remote-nodes#comments</comments>
		<pubDate>Thu, 29 Jul 2010 15:14:07 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[MIsc.Tips]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[nslookup]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=824</guid>
		<description><![CDATA[I recently had the need to get the ip address for a remote node. Wait, scratch that.. I had to get the IP addresses for about 60 remote nodes. You&#8217;re right&#8230; I probably could have typed nslookup targetNode 60 times. But I am a programmer! SO I decided to pass my choir off to a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the need to <strong>get the ip address for a remote node</strong>.  Wait, scratch that.. I had to <strong>get the IP addresses for about 60 remote nodes</strong>.</p>
<p>You&#8217;re right&#8230; I probably <em>could have</em> typed
<pre>nslookup targetNode</pre>
<p> 60 times. But I am a programmer! <strong>SO I decided to pass my choir off to a shell script.</strong></p>
<p>If you have a similar need, read on!<br />
<span id="more-824"></span></p>
<p>The script is simple, just add all target nodes as a space separated list, and run the file.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash </span>
<span style="color: #666666; font-style: italic;"># author: Edward A Webb (http://edwardawebb.com</span>
<span style="color: #666666; font-style: italic;"># license: Just use it! its like 10 lines of shell script...</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># add your actual nodes here.....</span>
<span style="color: #007800;">nodes</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> gonzo fenway einstein yogurt toxic babmbi rambo donna INXS etc... <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #007800;">ips</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;"># placeholder for results</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span> Determing IP addresses for provided nodes <span style="color: #000099; font-weight: bold;">\n</span> ignore these lines...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span> i = <span style="color: #000000;">0</span> ; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #800000;">${#nodes[@]}</span> ; i++ <span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #007800;">str</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>nslookup <span style="color: #800000;">${nodes[$i]}</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tail</span> <span style="color: #660033;">--lines</span>=<span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> <span style="color: #660033;">--lines</span>=<span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
	ips<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #007800;">$i</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$str</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cut</span> <span style="color: #660033;">-f</span> <span style="color: #000000;">2</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot; &quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span> COMPLETE<span style="color: #000099; font-weight: bold;">\n</span> Here are the results you care about..<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span> i = <span style="color: #000000;">0</span> ; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #800000;">${#ips[@]}</span> ; i++ <span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> address <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #800000;">${nodes[$i]}</span> is <span style="color: #800000;">${ips[$i]}</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> ip_results.txt
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/ip-addresses-remote-nodes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Backup all sub-directories with a Bash array loop</title>
		<link>http://www.edwardawebb.com/linux/backup-subdirectories-bash-array-loop</link>
		<comments>http://www.edwardawebb.com/linux/backup-subdirectories-bash-array-loop#comments</comments>
		<pubDate>Thu, 15 Apr 2010 22:02:05 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[MIsc.Tips]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=725</guid>
		<description><![CDATA[I manage lots of domains, and offer my clients free backup and recovery service. Nice selling perk, but I best be damn sure I am backing things up regularly.  Since there is no way my space-cadet brain would remember that, I rely on my &#8216;nix friends: bash, cron and tar to neatly package every sub-directory [...]]]></description>
			<content:encoded><![CDATA[<p>I manage lots of domains, and offer my clients free backup and recovery service.<br />
Nice selling perk, but I best be damn sure I am backing things up regularly.  Since there is no way my space-cadet brain would remember that, I rely on my &#8216;nix friends: <strong>bash, cron and tar</strong> to neatly package every sub-directory of my webroot into their own little tarballs.</p>
<p><strong>The bash script included after the break reads all directories into an array that we can loop through </strong>and manipulate as needed<strong>.</strong><br />
<span id="more-725"></span></p>
<h2>Background</h2>
<p>My webroot is pretty straightforward. Each subdirectory is the full URL of a site. Example:</p>
<pre lang="">
webroot
|-- baungenjar.com
|-- bythebootstrap.com
|-- cafe--espresso.com
|-- crm.webbmaster.org
|-- eaw-technologies.com
|-- edwardawebb.com
|-- entrepreneurmeetcapitalist.com
|-- kicksareforribs.com
|-- ollitech.com
|-- outlaw-photography.com
|-- piwik.baungenjar.com
|-- rendinaro.com
|-- riversidegrillnh.com
|-- sidi.webbmaster.org
|-- status.webbmaster.org
|-- steadfastsites.com
|-- stonybrookpottery.com
|-- survey.webbmaster.org
|-- top.webbmaster.org
|-- trippymedia.com
|-- webbmaster.org
`-- wishlist.webbmaster.org
</pre>
<p>So I want to take each directory and create a gzipped tarball using <em>tar -zcf</em>.    I don&#8217;t want to do any manual intervention.</p>
<p>*ALso, I want to exclude some directories. </p>
<h2>Solution</h2>
<p>This actually took me much longer than it should have. <strong>Too many articles insisted you should change the internal field separator (IFS) to a newline character and just use <em>ls</em></strong>.  Now in my training I was learn-ed that messing with IFS can be dangerous, and will disrupt many things, including any command that relies on options or arguments (i.e. ALL)<br />
<strong>So rather than make my entire script confirm to pesky newlines returned by ls, I did one simpler &#8211; eliminate the newlines in place of a decent token separator, like a space!</strong></p>
<p>To exclude directories I just use a magic file &#8220;.DONT_BACKUP&#8221; that the script checks for.</p>
<h2>Code</h2>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">#!/bin/bash
#
# Backup all directories within webroot
# use empty file &quot;.DONT_BACKUP&quot; to exclude any directory
&nbsp;
&nbsp;
# days to retain backup. Used by recycler script
DEFRETAIN=14
LOGFILE=/home/webb_e/site_backups/WebrootBackup.log
#
#
BU_FILE_COUNT=0
#
# and name of backup source subfolder under the users home
WEBDIR=webroot
#
# and name of dest folder for tar files
DESDIR=site_backups
&nbsp;
#alright, thats it for config, the rest is script
#########################################
&nbsp;
&nbsp;
cd ${HOME}/${WEBDIR}/
&nbsp;
&nbsp;
TODAY=`date`
BU_FILE_COUNT=0
suffix=$(date +%m-%d-%Y)
printf &quot;\n\n********************************************\n\tSite Backup r Log for:\n\t&quot; | tee -a $LOGFILE
echo $TODAY | tee -a $LOGFILE
printf &quot;********************************************\n&quot; $TODAY | tee -a $LOGFILE
echo &quot;see ${LOGFILE} for details&quot;
&nbsp;
#for DIR in $(ls | grep ^[a-z.]*$) 
&nbsp;
for DIR in $(ls | grep ^[a-z.]*$) 
do
	echo $DIR
	#tar the current directory
	if [ -f $DIR/.DONT_BACKUP ]
	then
&nbsp;
		printf &quot;\tSKIPPING $DIR as it contains ignore file\n&quot; | tee -a $LOGFILE
&nbsp;
	else
		cpath=${HOME}/${DESDIR}/${DIR}
		#
		#check if we need to make path
		#
		if [ -d $cpath ]
		then
			# direcotry exists, we're good to continue
			filler=&quot;umin&quot;
		else
			echo Creating $cpath
			mkdir -p $cpath
			echo $DEF_RETAIN &gt; $cpath/.RETAIN_RULE
		fi
		#
&nbsp;
		tar -zcf ${HOME}/${DESDIR}/${DIR}/${DIR}_$suffix.tar.gz ./$DIR
		BU_FILE_COUNT=$(( $BU_FILE_COUNT + 1 ))
	fi
&nbsp;
done
printf &quot;\n\n********************************************\n&quot; | tee -a $LOGFILE
echo $BU_FILE_COUNT sites were backed up
printf &quot;********************************************\n&quot; $TODAY | tee -a $LOGFILE</pre></div></div>

<h2>Result</h2>
<pre lang="">
$ ~/scripts/file_backups/SiteBackup.sh
see /home/myself/site_backups/WebrootBackup.log for details

********************************************
        Site Backup r Log for:
        Thu Apr 15 14:31:53 PDT 2010
********************************************
albums.stonybrookpottery.com
baungenjar.com
bythebootstrap.com
crm.webbmaster.org
digbiz.webroot.com
dotproject.webbmaster.org
edwardawebb.com
kicksareforribs.com
mantis.webbmaster.org
        SKIPPING mantis.webbmaster.org as it contains ignore file
ollitech.com
openx.webbmaster.org
piwik.baungenjar.com
rendinaro.com
riversidegrillnh.com
sidi.webbmaster.org
status.webbmaster.org
steadfastsites.com
stonybrookpottery.com
survey.webbmaster.org
svn.webbmaster.org
taskfreak.webbmaster.org
test.kicksareforribs.com
texpat.webbmaster.org
top.webbmaster.org
        Creating /home/myself/site_backups/top.webbmaster.org
trac.webbmaster.org
trippymedia.com
wave.webbmaster.org
webbmaster.org
wishlist.webbmaster.org

********************************************
33 sites were backed up
********************************************
</pre>
<p>But wait! We wanted to automate this whole thing right? And so we shall.</p>
<h2>Using Cron to automate the process</h2>
<p>If your using a webhost they likely provide a GUI to add cron jobs. If that&#8217;s the case you can just point to the full path where you saved the above script, select the interval and your good to go.</p>
<p>If your using this on your own server you&#8217;ll need to get your hands dirty with a crontab. You can open the crontab file in your editor of choice, or call it from the command line. IN this example we&#8217;ll rely in vi, my systems default editor.<br />
Create a crontab file if it does not already exist and open it for edit</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">crontab <span style="color: #660033;">-e</span></pre></div></div>

<p>You may see some existing lines or you may not. Just remember one job per line. THe layout may seem overwhelming at first, but its quite simple, and breaks down like this</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">min     hour     day    month    weekday     job_to_Run</pre></div></div>

<p>The values are in the respective ranges for day of week 0 is Sunday.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">0</span>-<span style="color: #000000;">59</span>    <span style="color: #000000;">0</span>-<span style="color: #000000;">23</span>     <span style="color: #000000;">1</span>-<span style="color: #000000;">31</span>    <span style="color: #000000;">1</span>-<span style="color: #000000;">12</span>     <span style="color: #000000;">0</span>-<span style="color: #000000;">6</span>        filename</pre></div></div>

<p>To omit a field replace it with an asterisk (*) which means all values. Alternately you may use comma separated lists. Although I believe it will treat any whitespace as a delimiter I use tabs to make the organization a little nicer.</p>
<p>So let&#8217;s suppose I want to run this job nightly, it is after all named DAILY sql backup <img src='http://www.edwardawebb.com/wp-includes/images/smilies/icon_smile.gif' alt="icon smile Backup all sub directories with a Bash array loop" class='wp-smiley' title="Backup all sub directories with a Bash array loop" /><br />
I will add the following line to my crontab</p>
<pre>
15    0     *    *   *     $HOME/scripts/file_backup.sh > logfile.log
</pre>
<p>This means every day @ 00:15 a.k.a 15 minutes past midnight it will run the script and print any output into the specified logfile.<br />
If you leave off the redirect to logfile it will email the user with the results. To omit any output use the handy standby
<pre>>/dev/null 2>&#038;1</pre>
<p>.</p>
<h2>More Help</h2>
<p><strong>If you are curious about the script that will actually recycle old backups, then I suggest <a href="http://edwardawebb.com/linux/log-recycler-script" rel="nofollow" >Log Recycler Script</a> which could easily be updated to handle .tar.gz files instead of .sql.gz files <img src='http://www.edwardawebb.com/wp-includes/images/smilies/icon_smile.gif' alt="icon smile Backup all sub directories with a Bash array loop" class='wp-smiley' title="Backup all sub directories with a Bash array loop" /> </strong></p>
<p><strong><br />
If you want to backup your MySQL databases, I have that too, <a href="http://edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases" rel="nofollow" >Shell script to backup multiple databases</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/backup-subdirectories-bash-array-loop/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multiple SSL Domains on Apache without Unique IPs</title>
		<link>http://www.edwardawebb.com/web-development/multiple-ssl-domains-apache-unique-ips</link>
		<comments>http://www.edwardawebb.com/web-development/multiple-ssl-domains-apache-unique-ips#comments</comments>
		<pubDate>Tue, 01 Sep 2009 13:19:40 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[dreamhost]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=565</guid>
		<description><![CDATA[So you host 13 domains on one server and want SSL certs for each domain. The cost of unique IPs is an obstacle indeed, but what if you didn't need any unique IP addresses?


IMpossible you say? Not with the release of Apache 2.2.13!

I stumbled on this nice little feature called SNI (or Server Name Indication) that allows multiple domains to share an IP and implement SSL without showing warnings to users or confusing Apache. ]]></description>
			<content:encoded><![CDATA[<p>So you host 13 domains on one server and want SSL certs for each domain.  The cost of unique IPs is an obstacle indeed, but what if you didn&#8217;t need any unique IP addresses?</p>
<p>IMpossible you say? Not with the release of Apache 2.2.13!</p>
<p>I stumbled on this nice little feature called SNI (or <em>Server Name Indication</em>) that allows multiple domains to share an IP and implement SSL without showing warnings to users or confusing Apache.  I found this beauty after reading another great article on Linux Magazine, <a href="http://www.linux-mag.com/cache/7480/1.html" rel="nofollow"  target="_blank">Ten Things You Didn&#8217;t KNow Apache (2.2) Could Do </a></p>
<p>So those of you running your own servers can take advantage by upgrading today!</p>
<p>For those of you relying on a Host you should start bombarding them with requests immediately. <strong>DreamHost members can <a href="https://panel.dreamhost.com/index.cgi?tree=home.sugg&amp;category=_all&amp;search=Support%20for%20name-bas" rel="nofollow" title="Vote for this Feature on all DreamHost servers."  target="_blank">vote up the already created suggestion  to implement this</a>.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/web-development/multiple-ssl-domains-apache-unique-ips/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Books I recommend</title>
		<link>http://www.edwardawebb.com/linux/books-recommend</link>
		<comments>http://www.edwardawebb.com/linux/books-recommend#comments</comments>
		<pubDate>Wed, 08 Jul 2009 21:43:13 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[Database Tips]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=509</guid>
		<description><![CDATA[Amazon.com Widgets]]></description>
			<content:encoded><![CDATA[<p><OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab" id="Player_2c0bc29f-ccdb-489a-ac1e-da93c888b804"  WIDTH="500px" HEIGHT="175px"> <PARAM NAME="movie" VALUE="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&#038;MarketPlace=US&#038;ID=V20070822%2FUS%2Fedawe-20%2F8010%2F2c0bc29f-ccdb-489a-ac1e-da93c888b804&#038;Operation=GetDisplayTemplate"><PARAM NAME="quality" VALUE="high"><PARAM NAME="bgcolor" VALUE="#FFFFFF"><PARAM NAME="allowscriptaccess" VALUE="always"><embed src="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&#038;MarketPlace=US&#038;ID=V20070822%2FUS%2Fedawe-20%2F8010%2F2c0bc29f-ccdb-489a-ac1e-da93c888b804&#038;Operation=GetDisplayTemplate" id="Player_2c0bc29f-ccdb-489a-ac1e-da93c888b804" quality="high" bgcolor="#ffffff" name="Player_2c0bc29f-ccdb-489a-ac1e-da93c888b804" allowscriptaccess="always"  type="application/x-shockwave-flash" align="middle" height="175px" width="500px"></embed></OBJECT> <NOSCRIPT><a href="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&#038;MarketPlace=US&#038;ID=V20070822%2FUS%2Fedawe-20%2F8010%2F2c0bc29f-ccdb-489a-ac1e-da93c888b804&#038;Operation=NoScript" rel="nofollow" >Amazon.com Widgets</a></NOSCRIPT></p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/books-recommend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP</title>
		<link>http://www.edwardawebb.com/web-development/keys-putty-cygwin-passwordless-login-ssh-scp</link>
		<comments>http://www.edwardawebb.com/web-development/keys-putty-cygwin-passwordless-login-ssh-scp#comments</comments>
		<pubDate>Sun, 10 May 2009 14:54:04 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[MIsc.Tips]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[pageant]]></category>
		<category><![CDATA[passwordless]]></category>
		<category><![CDATA[PuTTY]]></category>
		<category><![CDATA[remote server]]></category>
		<category><![CDATA[scp]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[ssh-agent]]></category>
		<category><![CDATA[WinSCP]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=460</guid>
		<description><![CDATA[<strong>Tools like PuTTY and Cygwin allows users trapped in a window's world to retain some of the power and functionality of 'nix platforms</strong>.  Together or independently they allow users on windows machines to SSH, SCP and interface with Linux, Unix, Solaris, or even AIX nodes.  The absolute best part?  You can generate a pair of keys to make remembering passwords a thing of a the past.   This is especially important to one's sanity if you work in an environment with 10s or 100s of different nodes that all have rotating IDs on different schedules.  

So my goal in the article that follows is to setup a powerful workstation that includes Cygwin, PuTTY, and WinSCP.  WinSCP is not a necessary tool, but I'll admit I like to resort to a graphical SCP tool every now and again.  <strong>Unlike a few other articles I have read I will not encourage you to use passphrase-less keys, just too risky in my mind. </strong> Instead we will just limit the number of times we need to enter that password to say about.... 1.

To recap, our Goals are;
<ul>
	<li>Install powerful windows based tools. (Cygwin, PuTTY and WinSCP)</li>
	<li>Generate a pair of 2048 bit RSA keys (With a passphrase)</li>
	<li>Disseminate the public key to all the nodes we know (or connect to)</li>
	<li>Employ Pageant and SSH-Agent to limit the need to enter that single passphrase.</li>
</ul>]]></description>
			<content:encoded><![CDATA[<p><strong>Tools like PuTTY and Cygwin allows users trapped in a window&#8217;s world to retain some of the power and functionality of &#8216;nix platforms</strong>.  Together or independently they allow users on windows machines to SSH, SCP and interface with Linux, Unix, Solaris, or even AIX nodes.  The absolute best part?  You can generate a pair of keys to make remembering passwords a thing of a the past.   This is especially important to one&#8217;s sanity if you work in an environment with 10s or 100s of different nodes that all have rotating IDs on different schedules.  </p>
<p>So my goal in the article that follows is to setup a powerful workstation that includes Cygwin, PuTTY, and WinSCP.  WinSCP is not a necessary tool, but I&#8217;ll admit I like to resort to a graphical SCP tool every now and again.  <strong>Unlike a few other articles I have read I will not encourage you to use passphrase-less keys, just too risky in my mind. </strong> Instead we will just limit the number of times we need to enter that password to say about&#8230;. 1.</p>
<p>To recap, our Goals are;</p>
<ul>
<li>Install powerful windows based tools. (Cygwin, PuTTY and WinSCP)</li>
<li>Generate a pair of 2048 bit RSA keys (With a passphrase)</li>
<li>Disseminate the public key to all the nodes we know (or connect to)</li>
<li>Employ Pageant and SSH-Agent to limit the need to enter that single passphrase.</li>
</ul>
<p>So let&#8217;s get started.<br />
<span id="more-460"></span><br />
<h2>Installing the Tools</h2>
<p>Most anyone who works with Unix nodes from a window&#8217;s desktop knows the joy of PuTTY. Perhaps a few less know about Cygwin.  These tools are a must have in any IT toolbox.</p>
<h3>Cygwin</h3>
<p>Cygwin, available <a href="http://www.cygwin.com/" rel="nofollow" title="Learn more about Cygwin and download a copy for yourself."  target="_blank">here</a>, allows Unix like commands to run in a windows command console.   When installing the utility we need to make sure to check off a few extras that are not part of the default install.</p>
<p>Kick off the install until you get to a list of the components to install. Expand the Net category and check off OpenSSH and OpenSSL.<br />
<a href="http://edwardawebb.com/wp-content/uploads/2009/05/cygwin_install.png" rel="nofollow" ><img class="aligncenter size-medium wp-image-462" title="Cygwin Install Options" src="http://edwardawebb.com/wp-content/uploads/2009/05/cygwin_install-300x146.png" alt="cygwin install 300x146 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="146" /></a> Let the installation complete normally otherwise.</p>
<h3>PuTTY</h3>
<p>You know all about PuTTY I am sure.  My only real advice here is to download the complete PuTTY suite of tools with the installer. There are two main perks to this.  1) You get all the goodies like PuTTYGen and Pageant. 2) If your running Vista you won&#8217;t get those annoying UAC alerts every time you kick it off.</p>
<p>You can find the PuTTY suite <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" rel="nofollow" title="Download all the PuTTY tools."  target="_blank">here</a>. Be sure to grab the one listed under &#8220;A Windows installer for everything except PuTTYtel.&#8221;</p>
<p>Don&#8217;t worry, if you already had the stand alone utility installed, it will preserve all yoru settings so long as you install to the same folder.</p>
<h3>WinSCP</h3>
<p>WinSCP is a graphical interface for moving files between your local machine and remote servers.  If you want to stay true to your terminals you can just stick with Cygwin and the SCP utility (which we&#8217;ve already installed).</p>
<p>Grab WinSCP from <a href="http://winscp.net/eng/download.php" rel="nofollow" title="Download WinSCP, an open source graphical SCP tool."  target="_blank">here</a>, no special install needed.</p>
<h2>Generating our Keys</h2>
<p>OK!  So now we can connect to our remote servers any way conceivable to man. Well maybe that&#8217;s an over statement, but I think our bases are pretty well covered.</p>
<p>The next hurdle is to create a pair of digital keys.  We keep one key (the private key) on our local machine, and never share it with anyone.  We disseminate (or distribute) the other key (public) out to any server we want to connect to.  The key pair will be reunited on connection allow us to authenticate without entering our password for the remote server.</p>
<p>First open up Cygwin.  Ahh isn&#8217;t she beautiful.</p>
<p>Type <em>ssh-keygen -t rsa</em> at the prompt and follow the queues entering information.  <strong>Be sure to enter a passphrase! </strong>You may accept the default path for a key location.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ssh-keygen</span> <span style="color: #660033;">-t</span> rsa
Generating public<span style="color: #000000; font-weight: bold;">/</span>private rsa key pair.
Enter <span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #c20cb9; font-weight: bold;">which</span> to save the key <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa<span style="color: #7a0874; font-weight: bold;">&#41;</span>:
Created directory <span style="color: #ff0000;">'/home/Eddie/.ssh'</span>.
Enter passphrase <span style="color: #7a0874; font-weight: bold;">&#40;</span>empty <span style="color: #000000; font-weight: bold;">for</span> no passphrase<span style="color: #7a0874; font-weight: bold;">&#41;</span>:
Enter same passphrase again:
Your identification has been saved <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.
Your public key has been saved <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.pub.
The key fingerprint is:
<span style="color: #000000;">74</span>:<span style="color: #000000;">17</span>:ef:<span style="color: #000000;">24</span>:e6:5f:1b:f3:e0:6a:1b:fe:ae:a6:fe:<span style="color: #000000;">24</span> Eddie<span style="color: #000000; font-weight: bold;">@</span>HP-dv6z-<span style="color: #000000;">420</span>
The key<span style="color: #ff0000;">'s randomart image is:
+--[ RSA 2048]----+
|  .-o.           |
|+ .o*  .         |
|+F .o . o        |
|..o  + .         |
|  -     S        |
|   -             |
|   +-  F  o      |
|.  .G . .        |
| o+*+o     o     |
+-----------------+</span></pre></div></div>

<p>Now since you should be in your home directory you can type <em> ls -a</em> and you should notice a new directory <em>.ssh</em> inside their will be your public (id-rsa.pub) and private (id-rsa) keys. If you chose an alternate path while generating the keys, be sure to move the private key into this folder.</p>
<h3>Disseminate our Public Key</h3>
<p>We&#8217;ll stick with Cygwin for a bit longer and use it&#8217;s scripting abilities to share our public key with any servers we want to connect to. If you only have one remote server in mind than a script is probly overkill, but you will want to follow the steps within the script. In my case I have about 20 servers, so I&#8217;ll take all the automation I can get.</p>
<h4>The Dissemination Scripts</h4>
<p>There are two scripts. One runs locally, and the other gets sent over SCP and then runs as our remote henchmen before being purged like a failed hitman.</p>
<h5>Script 1 &#8211; Called Locally </h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/bash</span>
<span style="color: #666666; font-style: italic;"># Author: Eddie Webb - edwardawebb.com</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Deploys a public SSH key to multiple remote nodes. It will convert from Putty Format</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Calls Script:</span>
<span style="color: #666666; font-style: italic;">#	addPublicKeyRemotely.sh</span>
&nbsp;
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">## Check arghuments</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Usage: <span style="color: #000099; font-weight: bold;">\n</span> %s PuttyPubKey<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#create a log file</span>
<span style="color: #007800;">LOGFILE</span>=Results.log
&nbsp;
&nbsp;
&nbsp;
<span style="color: #007800;">SERVERS</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> server1 server2 funnyname anotherserver <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #666666; font-style: italic;">#NOte: if your username is different on each node - make an array below that correspoinds to the node list above</span>
<span style="color: #007800;">USER</span>=YOUREMOTEUSERNAME
&nbsp;
<span style="color: #007800;">SSHKEY</span>=<span style="color: #007800;">$1</span>
<span style="color: #007800;">SSHKEYBASE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$1</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">SCRIPTPATH</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #666666; font-style: italic;">## loop thorugh all servers sending key and remote script - purges afer script runs.</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span> i = <span style="color: #000000;">0</span> ; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #800000;">${#SERVERS[@]}</span> ; i++ <span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> Sending to Host <span style="color: #800000;">${SERVERS[$i]}</span>
	<span style="color: #c20cb9; font-weight: bold;">scp</span> <span style="color: #007800;">$SSHKEY</span> <span style="color: #007800;">$SCRIPTPATH</span><span style="color: #000000; font-weight: bold;">/</span>addPublicKeyRemotely.sh <span style="color: #007800;">$USER</span><span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${SERVERS[$i]}</span>:~<span style="color: #000000; font-weight: bold;">/</span>
	<span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #007800;">$USER</span><span style="color: #000000; font-weight: bold;">@</span><span style="color: #800000;">${SERVERS[$i]}</span> <span style="color: #ff0000;">&quot;~/addPublicKeyRemotely.sh <span style="color: #007800;">$SSHKEYBASE</span>;rm -f ~/addPublicKeyRemotely.sh&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$LOGFILE</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> Key successfully pushed to <span style="color: #800000;">${SERVERS[$i]}</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$LOGFILE</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> SUCCESS
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> FAILED pushing key to <span style="color: #800000;">${SERVERS[$i]}</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$LOGFILE</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> FAILED
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p> </p>
<h5>Script 2 &#8211; Called remotely &#8211; Name important (addPublicKeyRemotely.sh)</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># Author: Eddie Webb - edwardawebb.com</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># Called by Script:</span>
<span style="color: #666666; font-style: italic;">#		promotePublicKey.sh</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Arguments:</span>
<span style="color: #666666; font-style: italic;">#		name of converted SSH key </span>
&nbsp;
<span style="color: #666666; font-style: italic;"># this file is uplaoded to remote serveres and called to handle remote work before being deleted.</span>
&nbsp;
&nbsp;
	<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> .ssh <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> .ssh
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #c20cb9; font-weight: bold;">touch</span> .ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys
	<span style="color: #c20cb9; font-weight: bold;">chmod</span> 0600 .ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys
	<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> .ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys
	<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> <span style="color: #007800;">$1</span></pre></div></div>

<p> </p>
<p>Run the first script specifying your <strong>PUBLIC</strong> key as the only parameter.<br />
Now the downside is that you will still need to enter your remote passwords for each server, but hey it will be the last time.<br />
The result should look something like;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">&nbsp;
$ scripts<span style="color: #000000; font-weight: bold;">/</span>promotePublicKey.sh .ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.pub
Sending to Host domain.com
YOURUSER<span style="color: #000000; font-weight: bold;">@</span>domain.com<span style="color: #ff0000;">'s password:
id_rsa.pub                                    100%  399     0.4KB/s   00:00
addPublicKeyRemotely.sh                       100%  387     0.4KB/s   00:00
YOURUSER@domain.com'</span>s password:
SUCCESS</pre></div></div>

<p> </p>
<h3>Testing Cygwin</h3>
<p>You should now be able to make a remote connection entering only your new key passphrase(the passwordless part is yet to come).</p>
<p> </p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> YOURUSER<span style="color: #000000; font-weight: bold;">@</span>domain.com
Enter passphrase <span style="color: #000000; font-weight: bold;">for</span> key <span style="color: #ff0000;">'/home/Eddie/.ssh/id_rsa'</span>:</pre></div></div>

<p>Don&#8217;t worry, you won&#8217;t always enter the passphrase, that was a test. Be patient with me <img src='http://www.edwardawebb.com/wp-includes/images/smilies/icon_smile.gif' alt="icon smile Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" class='wp-smiley' title="Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" /> </p>
<p> </p>
<p> </p>
<h3>Importing to PuTTY</h3>
<p>Putty uses its own format for private keys (PPK) so we need to import our openSSH private key and convert it to a PPK for Putty to use. We&#8217;ll do this without overwritting the private key we have (still needed by Cygwin).</p>
<p>Open up PuTTYgen from your start menu.</p>
<p>First <em>Load</em> your existing private key (C:\cygwin\home\&lt;YOURNAME&gt;\.ssh\id-rsa)</p>
<div id="attachment_464" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen1.png" rel="nofollow" ><img class="size-medium wp-image-464" title="Import existing key to PuTTYgen" src="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen1-300x289.png" alt="puttygen1 300x289 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="289" /></a><p class="wp-caption-text">Import existing key to PuTTYge</p></div>
<p> After you import the key you will be asked for your key&#8217;s passphrase before seeing the screen below. It lists the details about your public key.</p>
<div id="attachment_465" class="wp-caption aligncenter" style="width: 310px"><a href="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen2.png" rel="nofollow" ><img class="size-medium wp-image-465" title="The imported key in PuTTYgen" src="http://edwardawebb.com/wp-content/uploads/2009/05/puttygen2-300x287.png" alt="puttygen2 300x287 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="287" /></a><p class="wp-caption-text">The imported key in PuTTYgen</p></div>
<p>Finally click the <em>Save private key</em> button (highlighted in Yellow)  this will save the priavte key as a PPK file. I typically save this in my PuTTY installation directory under a folder names <em>Keys.</em> <strong>Do not overwrite your existing key</strong>, and keep the PPK extension. </p>
<p> </p>
<p> </p>
<h2>Repetitive Entry Avoidance (A.K.A. Enter the passphrase once, and only once)</h2>
<p>Now we need to modify PuTTY and Cygwin to keep our keys in memory so we only enter the passphrase once per session.</p>
<h3>Using Pageant</h3>
<p>Pageant, which installed with PuTTY, will hold the keys open for PuTTy and WinSCP.</p>
<p>Find the shortcut to Pageant in your start menu. Make a copy of the shortcut and paste it into your <em>Startup</em> menu. This will kick off pageant every time windows boots. However, we need to tell the shortcut to load our private key.</p>
<p>Now right-click that icon and select properties. <br />
<a href="http://edwardawebb.com/wp-content/uploads/2009/05/pageant1.png" rel="nofollow" ><img class="aligncenter size-medium wp-image-467" title="Pageant Startup Properties" src="http://edwardawebb.com/wp-content/uploads/2009/05/pageant1-300x300.png" alt="pageant1 300x300 Using passwordless login on PuTTY and Cygwin using Keys over SSH and SCP" width="300" height="300" /></a>Edit the entry that says <em>Target</em> and change it from;</p>
<p>&#8220;C:\Program Files (x86)\PuTTY\pageant.exe&#8221;</p>
<p>To;</p>
<p>&#8220;C:\Program Files (x86)\PuTTY\pageant.exe&#8221; &#8220;C:\Program Files (x86)\PuTTY\Keys\id-rsa.ppk&#8221; </p>
<p>Click <em>Apply</em> and then close the properties window.  </p>
<p>Now try clicking the icon. It should immediately ask you for your passphrase. This is the same prompt you will see next time you boot windows.</p>
<p>Go ahead an test out PuTTY now.  You will not be prompted for a password, and instead will see something like&#8217;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Using username <span style="color: #ff0000;">&quot;YOURUSER&quot;</span>.
Authenticating with public key <span style="color: #ff0000;">&quot;imported-openssh-key&quot;</span> from agent</pre></div></div>

<h3>Using SSH-Agent for Cygwin</h3>
<p>Cygwin doesn&#8217;t use PuTTY&#8217;s ppk file, so we need a manner to retain the private id-rsa key within our Cygwin sessions.</p>
<p>Add the following script to your <em>.bash_profile</em>;</p>
<p> </p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">## only ask for my SSH key passphrase once!</span>
<span style="color: #666666; font-style: italic;">#use existing ssh-agent if possible</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
   . <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent <span style="color: #000000; font-weight: bold;">&gt;</span> <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;">fi</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SSH_AGENT_PID</span>&quot;</span> <span style="color: #660033;">-o</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #780078;">`/usr/bin/ps -a|/usr/bin/egrep \&quot;^[ ]+$SSH_AGENT_PID\&quot;`</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
   <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">ssh-agent</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent
   . <span style="color: #800000;">${HOME}</span><span style="color: #000000; font-weight: bold;">/</span>.ssh-agent <span style="color: #000000; font-weight: bold;">&gt;</span> <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;">fi</span>
<span style="color: #c20cb9; font-weight: bold;">ssh-add</span> ~<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa</pre></div></div>

<p> </p>
<p>Save the file and hop back to Cygwin.  You can either restart Cygwin, or source the profile file to test this feature out. Since I left Cygwin open I&#8217;ll just source the file.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ . .bash_profile
Enter passphrase <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa:
Identity added: <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>Eddie<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Now you SSH to eighty different servers and not enter the passphrase again!</p>
<h2>Conclusion</h2>
<p>We&#8217;re done! Thanks for bearing with my article, I know it was not too concise, but I hope you forged through it. If you have any questions, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/web-development/keys-putty-cygwin-passwordless-login-ssh-scp/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Drop all tables from a MySQL Database without deletion</title>
		<link>http://www.edwardawebb.com/linux/drop-tables-mysql-database-deletion</link>
		<comments>http://www.edwardawebb.com/linux/drop-tables-mysql-database-deletion#comments</comments>
		<pubDate>Fri, 13 Feb 2009 22:25:52 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[Database Tips]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=425</guid>
		<description><![CDATA[This solution allows you to purge all tables from a database without actually deleting the database. This may not seem practical to those that have full rights and wonder.. &#8220;Why not just create a new DB?&#8221;. For others that are using a hosting plan or work for a large company with restrictive bureaucracy will appreciate [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This solution allows you to purge all tables from a database without actually deleting the database.</strong><br />
This may not seem practical to those that have full rights and wonder.. &#8220;Why not just create a new DB?&#8221;.<br />
For others that are using a hosting plan or work for a large company with restrictive bureaucracy will appreciate this simple tip.  The reason is that <strong>your account may only have specific rights on that Database</strong> and absolutely no rights on the hosting server.  Even if you had permission to delete the old DB, you would have to jump through hoops to get a new one created.  So in short, &#8220;Because we can&#8217;t&#8221;</p>
<p>It has also been pointed out as a way to maintain the schema.</p>
<p><span id="more-425"></span></p>
<h2>Write a script to loop through all current tables and drop them? &#8211; NO!</h2>
<p>You could get a listing of all tables, iterate through an loop and drop the tables, but let&#8217;s see if we can&#8217;t think of a one liner&#8230;</p>
<h2>Rely on mysqldump and mysql to do all the work? &#8211; YES!</h2>
<p>We need to drop tables, that&#8217;s obvious.  But how to get all the tables with drop command in hand.  What about our ever so faithful and functional friend mysqldump? Of course! Not only can mysqldump handle giving us the names of all the tables, but it can also hand us the drop command.</p>
<p><strong>You&#8217;ll need to execute this command where mysqldump and mysql binaries live, typically this is /usr/bin.</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysqldump -uuser_name <span style="color: #660033;">-psecretpassword</span> <span style="color: #660033;">--add-drop-table</span> database_name <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> ^DROP <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql  -uuser_name <span style="color: #660033;">-psecretpassword</span> database_name</pre></div></div>

<p>SO we pump out all the table and data from the database,use grep to trash everything but the lines that begin with the drop commands and pass that right back into mysql.  Works, but should we be passing and parsing all the data just to trash it? Probably not.</p>
<h2>Keeping the workload small &#8211; no data!</h2>
<p>Particularly for those of you that have rather large Databases we don&#8217;t want to waste time passing around data, so let&#8217;s leave it out entirely.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysqldump -uuser_name <span style="color: #660033;">-psecretpassword</span> <span style="color: #660033;">--no-data</span> <span style="color: #660033;">--add-drop-table</span> database_name <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> ^DROP <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql  -uuser_name <span style="color: #660033;">-psecretpassword</span> database_name</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/drop-tables-mysql-database-deletion/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Simple shell script to backup multiple mysql databases</title>
		<link>http://www.edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases</link>
		<comments>http://www.edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases#comments</comments>
		<pubDate>Thu, 12 Feb 2009 23:32:32 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[Database Tips]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqldump]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=306</guid>
		<description><![CDATA[To backup a mysql database from a unix command line is relatively simple.  It is equally easy to automate this task with a shell script and a crontab (cron jobs).  In my case I needed to backup ~15 unique databases and I despise repetitious code, so here&#8217;s what I came up with. **Update Added means [...]]]></description>
			<content:encoded><![CDATA[<p>To<strong> backup a mysql database from a unix command</strong> line is relatively simple.  It is equally easy to automate this task with a shell script and a crontab (cron jobs).  In my case I needed to backup ~15 unique databases and I despise repetitious code, so here&#8217;s what I came up with.<br />
**Update<br />
Added means to allow different User and password based on current DB.<br />
** ANother Update! &#8211; better <a href="#error-handling" rel="nofollow" >error handling</a>.<br />
<span id="more-306"></span></p>
<h2>The problem</h2>
<p>I have multiple databases that need to be backed up into different archive folders. Each database requires a unique host, username and password.</p>
<h2>THe solution</h2>
<p>The bash shell of course! First off we should all be familiar with mysqldump.  It lives idle in nearly every &#8216;nix box just waiting to dump a mysql database onto the screen, or file. ANd unless you want your mysqldump binary to be sad you should take full well use of it.</p>
<p>The most basic use of the program couldn&#8217;t be simpler, but it is happy to meet more complex needs as well. FOr this article we&#8217;ll keep it simple.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">mysqldump <span style="color: #660033;">-h</span> HOSTNAME <span style="color: #660033;">-u</span> USERAME <span style="color: #660033;">-pPASSWORD</span> DATABASE <span style="color: #000000; font-weight: bold;">&gt;</span> OUTPUTFILE</pre></div></div>

<p>now you can of course add additional switches, c and e are two I use pretty frequently. See your machine&#8217;s man pages to learn more.</p>
<p>But wait that only handles 1 DB on 1 host with 1 user and password. True. SO here&#8217;s where we take use of a script to make this puppy work overtime.</p>
<h2>The Shell Scripts</h2>
<h3>Many mysql Databases on one host</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#####</span>
<span style="color: #666666; font-style: italic;"># Set these values!</span>
<span style="color: #666666; font-style: italic;">####</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># space seperated list of domain names (will be used as part of the output path)</span>
<span style="color: #007800;">domains</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> name4subfolders inSQLfolderabove canbedomains orsomethingelse <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #666666; font-style: italic;">#list of corresponding DB names</span>
<span style="color: #007800;">sqldbs</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> fulldbname1 db2 db3 db4 <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#list of IDs and passwords</span>
<span style="color: #007800;">usernames</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> user1 user2 user3 user <span style="color: #000000;">4</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">passwords</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> pass1 pass2 pass3 pass4 <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Directory to save generated sql files (domain name is appended)</span>
<span style="color: #007800;">opath</span>=<span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># your mysql host</span>
<span style="color: #007800;">mysqlhost</span>=mysql.webbmaster.org
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#####</span>
<span style="color: #666666; font-style: italic;"># End of config values</span>
<span style="color: #666666; font-style: italic;">#####</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#date to append</span>
<span style="color: #007800;">suffix</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>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#run on each domain</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span> i = <span style="color: #000000;">0</span> ; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #800000;">${#domains[@]}</span> ; i++ <span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #666666; font-style: italic;">#set current output path</span>
	<span style="color: #007800;">cpath</span>=<span style="color: #007800;">$opath</span><span style="color: #800000;">${domains[$i]}</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#check if we need to make path</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$cpath</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;"># direcotry exists, we're good to continue</span>
		<span style="color: #007800;">filler</span>=<span style="color: #ff0000;">&quot;just some action to prevent syntax error&quot;</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #666666; font-style: italic;">#we need to make the directory</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> Creating <span style="color: #007800;">$cpath</span>
		<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #007800;">$cpath</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#now do the backup</span>
	<span style="color: #007800;">SQLFILE</span>=<span style="color: #800000;">${cpath}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #800000;">${sqldbs[$i]}</span>_<span style="color: #007800;">$suffix</span>.sql.gz
&nbsp;
	mysqldump <span style="color: #660033;">-c</span> <span style="color: #660033;">-h</span> <span style="color: #007800;">$mysqlhost</span> <span style="color: #660033;">--user</span> <span style="color: #800000;">${usernames[$i]}</span> <span style="color: #660033;">--password</span>=<span style="color: #800000;">${passwords[$i]}</span> <span style="color: #800000;">${sqldbs[$i]}</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span>error <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">gzip</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$SQLFILE</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-s</span> error <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>	   
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;WARNING: An error occured while attempting to backup %s  <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>Error:<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span> <span style="color: #800000;">${sqldbs[$i]}</span> 
		<span style="color: #c20cb9; font-weight: bold;">cat</span> error
		<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> er
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;%s was backed up successfully to %s<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #800000;">${sqldbs[$i]}</span> <span style="color: #007800;">$SQLFILE</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>In either case you&#8217;ll want to save it to a file, let&#8217;s say&#8230;    daily_sql_backup.sh<br />
And then make the script executable</p>

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

<p>Now you can test the script by calling it by name</p>

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

<p><strong><br />
Sweet, a single command will backup any databases we include in the script. And we can call it again and again</strong>.</p>
<p>A simple output reports the results;</p>

<div class="wp_syntax"><div class="code"><pre class="unix" style="font-family:monospace;">database1 was backed up successfully to /home/YOURNAME/sql_dumps/site1.com/database1_2009-01-14.sql.gz
&nbsp;
taskfreak_database was backed up successfully to /home/YOURNAME/sql_dumps/taskfreak.sitetwo.com/taskfreak_database_2009-01-14.sql.gz
&nbsp;
mantis_database was backed up successfully to /home/YOURNAME/sql_dumps/mantios.yetanother.org/mantis_database_2009-01-14.sql.gz</pre></div></div>

<h3>Error Reporting<a name="error-handling">&nbsp;</a></h3>
<p>I recently had to update the error handling because it was letting failures pass by!</p>
<p>That was because mysqldump would fail, throw an error to stderr, but  gzip would then come along and happily report that is successfully compressed nothing!</p>
<p>The new model outputs any errors to a file named &#8220;error&#8221; before everything is piped into gzip and the error code is lost.  We then check for the file, and if present show it to the user (log it) before deleting the file and moving on.</p>
<p>So in a bad scenario I would now see:</p>
<pre>
Attempting to run MySQL dump on 2 databases
domain1.com
domain2.com

domain1_com was backed up successfully to /home/user/sql_dumps/
domain1/domain1_com_2011_05_05.sql.gz

WARNING: An error occured while attempting to backup domain2
        Error:
        mysqldump: Got error: 1045: Access denied for user 'domain2_com'@'domain2.com' (using password: YES) when trying to connect
</pre>
<p>&nbsp;</p>
<p>But wait! We wanted to automate this whole thing right? And so we shall.</p>
<h2>Using Cron to automate the process</h2>
<p>If your using a webhost they likely provide a GUI to add cron jobs. If that&#8217;s the case you can just point to the full path where you saved the above script, select the interval and your good to go.</p>
<p>If your using this on your own server you&#8217;ll need to get your hands dirty with a crontab. You can open the crontab file in your editor of choice, or call it from the command line. IN this example we&#8217;ll rely in vi, my systems default editor.<br />
Create a crontab file if it does not already exist and open it for edit</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">crontab <span style="color: #660033;">-e</span></pre></div></div>

<p>You may see some existing lines or you may not. Just remember one job per line. THe layout may seem overwhelming at first, but its quite simple, and breaks down like this</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">min     hour     day    month    weekday     job_to_Run</pre></div></div>

<p>The values are in the respective ranges for day of week 0 is Sunday.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">0</span>-<span style="color: #000000;">59</span>    <span style="color: #000000;">0</span>-<span style="color: #000000;">23</span>     <span style="color: #000000;">1</span>-<span style="color: #000000;">31</span>    <span style="color: #000000;">1</span>-<span style="color: #000000;">12</span>     <span style="color: #000000;">0</span>-<span style="color: #000000;">6</span>        filename</pre></div></div>

<p>To omit a field replace it with an asterisk (*) which means all values. Alternately you may use comma separated lists. Although I believe it will treat any whitespace as a delimiter I use tabs to make the organization a little nicer.</p>
<p>So let&#8217;s suppose I want to run this job nightly, it is after all named DAILY sql backup <img src='http://www.edwardawebb.com/wp-includes/images/smilies/icon_smile.gif' alt="icon smile Simple shell script to backup multiple mysql databases" class='wp-smiley' title="Simple shell script to backup multiple mysql databases" /><br />
I will add the following line to my crontab</p>
<pre>
15    0     *    *   *     $HOME/scripts/daily_sql_backup.sh > logfile.log
</pre>
<p>This means every day @ 00:15 a.k.a 15 minutes past midnight it will run the script and print any output into the specified logfile.<br />
If you leave off the redirect to logfile it will email the user with the results. To omit any output use the handy standby
<pre>>/dev/null 2>&#038;1</pre>
<p>.</p>
<p>well I think that covers it. THere&#8217;s tons of good resources to learn more about any particular topic, but I would be happy to field comments.</p>
<h3>The End Result</h3>
<p>After your newly created cron jobs have the chance to run for a few days you&#8217;ll end up with a nice and neat directory structure like this;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">sql_dumps<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb.com
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">13</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">14</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">15</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">16</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">17</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">18</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">`</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">19</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>-- mantis.mainsite.org
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">13</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">14</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">15</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">16</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">17</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">18</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">`</span>-- mainsite_mantis_01-<span style="color: #000000;">19</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">`</span>-- taskfreak.mainsite.org
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">11</span>-<span style="color: #000000;">2009</span>
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">11</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">12</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">13</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">14</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">15</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">16</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">17</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">18</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">`</span>-- mainsite_taskfreak_01-<span style="color: #000000;">19</span>-<span style="color: #000000;">2009</span>.sql.gz</pre></div></div>

<p>Note: this example would generate 3 files each night. After 1 month thats ~150 files depending on the month. That&#8217;s why I also wrote a simple <a href="http://edwardawebb.com/linux/log-recycler-script" rel="nofollow" >Recycler script</a> to purge all old files. <del datetime="2009-01-18T01:16:12+00:00">As soon as I draft that article I&#8217;ll ad the link here.</del></p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Scope Issue in Bash While Loops</title>
		<link>http://www.edwardawebb.com/linux/scope-issue-bash-loops</link>
		<comments>http://www.edwardawebb.com/linux/scope-issue-bash-loops#comments</comments>
		<pubDate>Sat, 07 Feb 2009 15:30:32 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[read]]></category>
		<category><![CDATA[while]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=376</guid>
		<description><![CDATA[I was writing a pretty complex Log Recylcer script that handles rotation, purging and compression.  I wanted to print a nice summary at the end with all the counts.  I got incredibly frustrated when a simple variable increment seemed to have scope issue. I can only re-create the issue using a pipe and read. Background For [...]]]></description>
			<content:encoded><![CDATA[<p>I was writing a pretty complex Log Recylcer script that handles rotation, purging and compression.  I wanted to print a nice summary at the end with all the counts.  I got incredibly frustrated when a simple <strong>variable increment seemed to have scope issue</strong>.<strong> I can only re-create the issue using a pipe and read</strong>.</p>
<h2>Background</h2>
<p> For those of you familiar with Bash you know that a variable declared inside an if statement or loop can usually be accessed outside that block without issue. unlike other languages (PHP or Java for example) where a variable must be initialized outside the block first. In Bash anything declared inside a block is preserved for the life of the script.   <strong>Except when that block happens to be a while loop using read from a piped command!</strong><br />
<span id="more-376"></span></p>
<h2>What am I talking about?</h2>
<p>Let us look at an example. Feel free to pop these 3 scripts into your console to learn along with us.</p>
<h3>Bash script NOT requiring initialized variable</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#declare nothing for LOOPCOUNT!</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#but we'll need something for our while loop</span>
<span style="color: #007800;">i</span>=<span style="color: #000000;">0</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$i</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">5</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;LOOPCOUNT is %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$LOOPCOUNT</span>
	<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>LOOPCOUNT++<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
	<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>i++<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #666666; font-style: italic;">#our count will be preserved</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Final LOOPCOUNT is %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$LOOPCOUNT</span></pre></div></div>

<h4>This will print</h4>

<div class="wp_syntax"><div class="code"><pre class="unix" style="font-family:monospace;">eddie@linux-cv2g:~/Scripts&gt; ./LoopDemo.sh
LOOPCOUNT is 0
LOOPCOUNT is 1
LOOPCOUNT is 2
LOOPCOUNT is 3
LOOPCOUNT is 4
Final LOOPCOUNT is 4</pre></div></div>

<p>As you can see, despite the fact that LOOPCOUNT was first introduced inside the While Loop it is still available after the loop has exited.  As I mentioned before this is not true of languages like PHP or Java.</p>
<h3>Bash Script ignoring initialized variable !</h3>
<p>Now here&#8217;s the meat of this article. Despite declaring the variable, and incrementing it properly,  as soon as we leave the loop we lose the value!</p>
<p>This type of while loop is useful for reading each line of a file, or each entry in a directory listing.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#ls will list all files in this directory, we pump that through a pipe to While which will act on each entry</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #c20cb9; font-weight: bold;">read</span> LINE
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;LOOPCOUNT is %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$LOOPCOUNT</span>
	<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>LOOPCOUNT++<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #666666; font-style: italic;">#our count will NOT be preserved</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Final LOOPCOUNT is %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$LOOPCOUNT</span></pre></div></div>

<p>Since my demo folder has 8 files in it&#8230;</p>
<h4>This will print</h4>

<div class="wp_syntax"><div class="code"><pre class="unix" style="font-family:monospace;">LOOPCOUNT is 0
LOOPCOUNT is 1
LOOPCOUNT is 2
LOOPCOUNT is 3
LOOPCOUNT is 4
LOOPCOUNT is 5
LOOPCOUNT is 6
LOOPCOUNT is 7
Final LOOPCOUNT is 0</pre></div></div>

<p>Zoot ALors!  The variable has amnesia and forgot it&#8217;s value!!</p>
<h3>Bash Script using While Loop and Read is tamed</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#if we break up the ls and while commands we can fix this issue</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">&gt;</span> filelist
&nbsp;
<span style="color: #666666; font-style: italic;">#set stdin to the file listing we jsut made</span>
<span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">&lt;</span>filelist
&nbsp;
<span style="color: #666666; font-style: italic;">#now act on each line in stdin</span>
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #c20cb9; font-weight: bold;">read</span> LINE
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;LOOPCOUNT is %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$LOOPCOUNT</span>
	<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>LOOPCOUNT++<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #666666; font-style: italic;">#our count will once again be preserved</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Final LOOPCOUNT is %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$LOOPCOUNT</span></pre></div></div>

<h4>This will print</h4>

<div class="wp_syntax"><div class="code"><pre class="unix" style="font-family:monospace;">LOOPCOUNT is 0
LOOPCOUNT is 1
LOOPCOUNT is 2
LOOPCOUNT is 3
LOOPCOUNT is 4
LOOPCOUNT is 5
LOOPCOUNT is 6
LOOPCOUNT is 7
LOOPCOUNT is 8
Final LOOPCOUNT is 8</pre></div></div>

<p>(The ls command includes our new script which explains the higher count)</p>
<h2>Summary</h2>
<p><strong><br />
My best guess </strong>is that using a command like</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #c20cb9; font-weight: bold;">read</span> LINE; <span style="color: #000000; font-weight: bold;">do</span></pre></div></div>

<p> opens a sub-shell for the duration of the loop. </p>
<p>This would explain while the value is maintained within the loop but lost immediately after.</p>
<p>I would love to hear from some Bash gurus on this topic!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/scope-issue-bash-loops/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Log Recycler Script</title>
		<link>http://www.edwardawebb.com/linux/log-recycler-script</link>
		<comments>http://www.edwardawebb.com/linux/log-recycler-script#comments</comments>
		<pubDate>Sun, 18 Jan 2009 01:15:39 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[MIsc.Tips]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[delete]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[recycler]]></category>
		<category><![CDATA[turn over]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=321</guid>
		<description><![CDATA[So when I wrote the article that introduced a script to generate mysql backup files for multiple databases I mentioned the trouble that will occur if you don&#8217;t get a handle on some means to retire old files. This applies to log files, mysql backups, or just about any other type of file that is [...]]]></description>
			<content:encoded><![CDATA[<p>So when I wrote the article that introduced a <a href="http://edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases" rel="nofollow" >script to generate mysql backup files for multiple databases</a> I mentioned the trouble that will occur if you don&#8217;t get a handle on <strong>some means to retire old files</strong>.</p>
<p>This applies to log files, mysql backups, or just about any other type of file that is created on a recurring basis.  You don&#8217;t need a error log from 134 days ago, but error logs for the past week could be very useful. So what do you do? Why recycle of course.</p>
<p><strong>This article shares a simple shell script to purge any files older than X days</strong>, where X is of course a number allowing for flexibility.<strong>  It is very simple to use a shell script to delete log files, or in this example sql backups.</strong></p>
<p><span id="more-321"></span></p>
<h2>The problem</h2>
<p>Your server is being overrun with numerous files that just hang around long after they have served there useful life. These files may be small or large, but something about leaving unused files hanging around doesn&#8217;t feel right.</p>
<p>After just a few days of mysql backups I end up with a directory structure like this;</p>
<pre>
sql_dumps/
|-- edwardawebb.com
|   |-- edwardawebb_wordpress_01-13-2009.sql.gz
|   |-- edwardawebb_wordpress_01-14-2009.sql.gz
|   |-- edwardawebb_wordpress_01-15-2009.sql.gz
|   |-- edwardawebb_wordpress_01-16-2009.sql.gz
|   |-- edwardawebb_wordpress_01-17-2009.sql.gz
|   |-- edwardawebb_wordpress_01-18-2009.sql.gz
|   `-- edwardawebb_wordpress_01-19-2009.sql.gz
|-- mantis.mainsite.org
|   |-- mainsite_mantis_01-13-2009.sql.gz
|   |-- mainsite_mantis_01-14-2009.sql.gz
|   |-- mainsite_mantis_01-15-2009.sql.gz
|   |-- mainsite_mantis_01-16-2009.sql.gz
|   |-- mainsite_mantis_01-17-2009.sql.gz
|   |-- mainsite_mantis_01-18-2009.sql.gz
|   `-- mainsite_mantis_01-19-2009.sql.gz
`-- taskfreak.mainsite.org
    |-- mainsite_taskfreak_01-11-2009
    |-- mainsite_taskfreak_01-11-2009.sql.gz
    |-- mainsite_taskfreak_01-12-2009.sql.gz
    |-- mainsite_taskfreak_01-13-2009.sql.gz
    |-- mainsite_taskfreak_01-14-2009.sql.gz
    |-- mainsite_taskfreak_01-15-2009.sql.gz
    |-- mainsite_taskfreak_01-16-2009.sql.gz
    |-- mainsite_taskfreak_01-17-2009.sql.gz
    |-- mainsite_taskfreak_01-18-2009.sql.gz
    `-- mainsite_taskfreak_01-19-2009.sql.gz
</pre>
<p>Although 24 files  may seem manageable, those who deal with log files and multiple sites know that this can quickly get out of hand.</p>
<h2>The solution</h2>
<p>We lazily create a shell script to run at weekly intervals to purge all those older files and send them off to the bit bucket.</p>
<p>Only files older than X days should be deleted, we&#8217;ll leave all the fresh and potentially needed logs/backups in place</p>
<p>This example assumes mysql logs with the .sql or .sql.gz extensions.</p>
<h3>shell script to purge outdated files</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#if you use this script you must attribute to me Eddie - Edwardawebb.com 1/14/09</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#this script will run through all nested directories of a parent just killing off all matching files.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">######</span>
<span style="color: #666666; font-style: italic;">### Set these values</span>
<span style="color: #666666; font-style: italic;">######</span>
&nbsp;
<span style="color: #666666; font-style: italic;">## default days to retain (override with .RETAIN_RULE in specific directory</span>
<span style="color: #007800;">DEFRETAIN</span>=<span style="color: #000000;">60</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#want to append the activity to a log? good idea, add its location here</span>
<span style="color: #007800;">LOGFILE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">pwd</span><span style="color: #000000; font-weight: bold;">`/</span>Recycler.log
&nbsp;
<span style="color: #666666; font-style: italic;"># enter the distinguishing extension, or portion of the filename here (eg. log, txt, etc.)</span>
<span style="color: #007800;">EXTENSION</span>=sql
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#the absolute path of folder to begin purging</span>
<span style="color: #666666; font-style: italic;">#this is the top most file to begin the attack, all sub directories contain lowercase letters and periods are game.</span>
<span style="color: #007800;">SQLDIR</span>=<span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>sql_dumps
&nbsp;
<span style="color: #666666; font-style: italic;">#####</span>
<span style="color: #666666; font-style: italic;">##   End user configuartion</span>
<span style="color: #666666; font-style: italic;">#####</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#this note will remind you that you have a log in case your getting emails form a cron job or something</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> see <span style="color: #007800;">$LOGFILE</span> <span style="color: #000000; font-weight: bold;">for</span> details
&nbsp;
<span style="color: #666666; font-style: italic;">#jump to working directory</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$SQLDIR</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#if your sub-dirs have some crazy characters you may adjust this regex</span>
<span style="color: #007800;">DIRS</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> ^<span style="color: #7a0874; font-weight: bold;">&#91;</span>a-z.<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">*</span>$<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
&nbsp;
<span style="color: #007800;">TODAY</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>********************************************<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>SQL Recycler Log for:<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$TODAY</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;********************************************<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$TODAY</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> DIR <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$DIRS</span> 
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #7a0874; font-weight: bold;">pushd</span> <span style="color: #007800;">$DIR</span> <span style="color: #000000; font-weight: bold;">&gt;/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null
	<span style="color: #007800;">HERE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">pwd</span><span style="color: #000000; font-weight: bold;">`</span>
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$HERE</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> .RETAIN_RULE <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>default Retain period being overridden<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
		<span style="color: #c20cb9; font-weight: bold;">read</span> RETAIN <span style="color: #000000; font-weight: bold;">&lt;</span> .RETAIN_RULE
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #007800;">RETAIN</span>=<span style="color: #007800;">$DEFRETAIN</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>purging files older than %s days<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #800000;">${RETAIN}</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
&nbsp;
	<span style="color: #007800;">OLDFILES</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #660033;">-mtime</span> +<span style="color: #800000;">${RETAIN}</span> <span style="color: #660033;">-regex</span> .<span style="color: #000000; font-weight: bold;">*</span><span style="color: #800000;">${EXTENSION}</span>.<span style="color: #000000; font-weight: bold;">*`</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">--</span> <span style="color: #007800;">$OLDFILES</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>No files matching purge criteria<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>SQL Files being Delete from <span style="color: #007800;">$HERE</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\t</span>%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #007800;">$OLDFILES</span>  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
 	<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> <span style="color: #007800;">$OLDFILES</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>	
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Error while deleting last set&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
		<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">2</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Success<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tee</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$LOGFILE</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #7a0874; font-weight: bold;">popd</span> <span style="color: #000000; font-weight: bold;">&gt;/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>did you notice the bit about .RETAIN_RULE?  good!<br />
I added this after I realized that I don&#8217;t treat all my sites equally. For this very blog which is backed up daily I only need 3-4 days back max. But for other sites that I back up monthly I need to keep the default 60 days or 1-2 files.</p>
<p>So I set the default in the script to 60. But I allow it to be overwritten by adding a simple text file to any directory. If a file .RETAIN_RULE is present it will read the first line (and first line only!) for a new value, example;</p>
<h4>$HOME/sql_dumps/dailysite.com/.RETAIN_RULE</h4>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">5</span>
<span style="color: #666666; font-style: italic;">#only keep files in this single directory around for 5 days</span></pre></div></div>

<p>notice i comment after the actual data!</p>
<p>This means my actual directory structure including retain rules looks more like;</p>
<pre lang="bash" hl_start="4" hl_count="1">
#tree -a sql_dumps
sql_dumps/
|-- edwardawebb.com
|   |-- .RETAIN_RULE
|   |-- edwardawebb_wordpress_01-13-2009.sql.gz
|   |-- edwardawebb_wordpress_01-14-2009.sql.gz
|   |-- edwardawebb_wordpress_01-15-2009.sql.gz
|   |-- edwardawebb_wordpress_01-16-2009.sql.gz
|   |-- edwardawebb_wordpress_01-17-2009.sql.gz
|   |-- edwardawebb_wordpress_01-18-2009.sql.gz
|   `-- edwardawebb_wordpress_01-19-2009.sql.gz
|-- mantis.mainsite.org
|   |-- .RETAIN_RULE
|   |-- mainsite_mantis_01-13-2009.sql.gz
|   |-- mainsite_mantis_01-14-2009.sql.gz
|   |-- mainsite_mantis_01-15-2009.sql.gz
|   |-- mainsite_mantis_01-16-2009.sql.gz
|   |-- mainsite_mantis_01-17-2009.sql.gz
|   |-- mainsite_mantis_01-18-2009.sql.gz
|   `-- mainsite_mantis_01-19-2009.sql.gz
`-- taskfreak.mainsite.org
    |-- mainsite_taskfreak_01-11-2009
    |-- mainsite_taskfreak_01-11-2009.sql.gz
    |-- mainsite_taskfreak_01-12-2009.sql.gz
    |-- mainsite_taskfreak_01-13-2009.sql.gz
    |-- mainsite_taskfreak_01-14-2009.sql.gz
    |-- mainsite_taskfreak_01-15-2009.sql.gz
    |-- mainsite_taskfreak_01-16-2009.sql.gz
    |-- mainsite_taskfreak_01-17-2009.sql.gz
    |-- mainsite_taskfreak_01-18-2009.sql.gz
    `-- mainsite_taskfreak_01-19-2009.sql.gz
</pre>
<h3>The Result</h3>
<p>So as the script walks through the structure above it prints a log to the effect of;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">see <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/&lt;</span>USERNAME<span style="color: #000000; font-weight: bold;">&gt;/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>Recycler.log <span style="color: #000000; font-weight: bold;">for</span> details
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">********************************************</span>
	SQL Recycler Log <span style="color: #000000; font-weight: bold;">for</span>:
	Sun Feb <span style="color: #000000;">8</span> 00:00:07 PST <span style="color: #000000;">2009</span>
<span style="color: #000000; font-weight: bold;">********************************************</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>MYUSERNAME<span style="color: #000000; font-weight: bold;">/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>edwardawebb.com
       	default Retain period being overridden
	purging files older than <span style="color: #000000;">4</span> days
	SQL Files being Delete from <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>masterkeedu<span style="color: #000000; font-weight: bold;">/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>edwardawebb.com
		.<span style="color: #000000; font-weight: bold;">/</span>edwardawebb_wordpress_01-<span style="color: #000000;">28</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>edwardawebb_wordpress_02-03-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>edwardawebb_wordpress_01-<span style="color: #000000;">29</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>edwardawebb_wordpress_02-02-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>edwardawebb_wordpress_01-<span style="color: #000000;">31</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>edwardawebb_wordpress_01-<span style="color: #000000;">30</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>edwardawebb_wordpress_02-01-<span style="color: #000000;">2009</span>.sql.gz
	Success
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>MYUSERNAME<span style="color: #000000; font-weight: bold;">/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>mantis.mainsite.org
	default Retain period being overridden
	purging files older than <span style="color: #000000;">4</span> days
	SQL Files being Delete from <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>masterkeedu<span style="color: #000000; font-weight: bold;">/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>mantis.mainsite.org
		.<span style="color: #000000; font-weight: bold;">/</span>webbmaster_mantis_01-<span style="color: #000000;">30</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>webbmaster_mantis_01-<span style="color: #000000;">31</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>webbmaster_mantis_02-01-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>webbmaster_mantis_01-<span style="color: #000000;">27</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>webbmaster_mantis_01-<span style="color: #000000;">29</span>-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>webbmaster_mantis_02-02-<span style="color: #000000;">2009</span>.sql.gz
		.<span style="color: #000000; font-weight: bold;">/</span>webbmaster_mantis_01-<span style="color: #000000;">28</span>-<span style="color: #000000;">2009</span>.sql.gz
	Success
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>MYUSERNAME<span style="color: #000000; font-weight: bold;">/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>taskfreak.mainsite.org
        purging files older than <span style="color: #000000;">60</span> days
        No files matching purge criteria
        Success</pre></div></div>

<p>As with any article I welcome feedback or questions!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/log-recycler-script/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
