<?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>Linux How-Tos and Indie Rock by seanp2k.com &#187; Linux</title>
	<atom:link href="http://seanp2k.com/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://seanp2k.com</link>
	<description>Linux Tips, Tricks, Hacks, Snarky commentary, and Indie Rock all at seanp2k.com</description>
	<lastBuildDate>Tue, 09 Feb 2010 15:10:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Fixing wget file names in bash</title>
		<link>http://seanp2k.com/2009/12/fixing-wget-file-names-in-bash/</link>
		<comments>http://seanp2k.com/2009/12/fixing-wget-file-names-in-bash/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 10:45:18 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[bash fix names]]></category>
		<category><![CDATA[fix file names]]></category>
		<category><![CDATA[fix names]]></category>
		<category><![CDATA[remove sequence]]></category>
		<category><![CDATA[rename]]></category>
		<category><![CDATA[renane files]]></category>
		<category><![CDATA[repair name]]></category>
		<category><![CDATA[repair names]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[wget]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=106</guid>
		<description><![CDATA[I downloaded a bunch of images using wget. The original file names were the same 6 names from 40 different pages. wget names those like this: 01_resize.jpg 01_resize.jpg.1 01_resize.jpg.2 etc. The other files were: 02_resize.jpg 03_resize.jpg etc, up to 6. Here is what I came up with that gives each file a unique name and [...]]]></description>
			<content:encoded><![CDATA[<p>I downloaded a bunch of images using wget.</p>
<p>The original file names were the same 6 names from 40 different pages.  wget names those like this:<br />
01_resize.jpg<br />
01_resize.jpg.1<br />
01_resize.jpg.2</p>
<p>etc.</p>
<p>The other files were:<br />
02_resize.jpg<br />
03_resize.jpg</p>
<p>etc, up to 6.</p>
<p>Here is what I came up with that gives each file a unique name and a valid extension ( 01_resize.jpg.02 becomes 02_01_resize.jpg ) (you can yell at me for parsing the output of &#8216;ls&#8217; later)<br />
<code><br />
for i in $(ls); do<br />
        seq=$(echo $i | cut -d. -f 3)<br />
        fname=$(echo $i | cut -d. -f 1-2)<br />
        mv $i $seq\_$fname<br />
done<br />
</code><br />
Hopefully it&#8217;s of some use to someone!  I&#8217;m basically grabbing the different parts of the filename using cut with a delimiter of &#8216;.&#8217; ; that&#8217;s where the magic is.  There&#8217;s probably a more efficient way of doing this, but it&#8217;s what made sense to my brain after being up for 24 hours.</p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2009/12/fixing-wget-file-names-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>If sites resolve to server, print URLs</title>
		<link>http://seanp2k.com/2009/09/if-sites-resolve-to-server-print-urls/</link>
		<comments>http://seanp2k.com/2009/09/if-sites-resolve-to-server-print-urls/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 21:58:51 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[do while]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[loop]]></category>
		<category><![CDATA[magento]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=91</guid>
		<description><![CDATA[UPDATED: now works with most apache installs and is more portable / useful: http://ip2k.com/sitelist.sh This bash script combines many useful little tricks that you may be interested in even if you don&#8217;t need the whole thing. Some include: - Print a list of IPs on the linux system - Print a list of websites hosted [...]]]></description>
			<content:encoded><![CDATA[<p>UPDATED: now works with most apache installs and is more portable / useful:</p>
<p>http://ip2k.com/sitelist.sh</p>
<p>This bash script combines many useful little tricks that you may be interested in even if you don&#8217;t need the whole thing.  Some include:</p>
<p>- Print a list of IPs on the linux system<br />
- Print a list of websites hosted on the server that match a certain pattern (app = Magento in this case)<br />
- Looping</p>
<p><code><br />
trap sorry INT<br />
#Two levels of debugging, 1 and 2.  1 shows just pings, 2 shows everything.<br />
dbg=0</p>
<p>function prnt {<br />
        echo -e "\e[1;36m[ $1 ]\e[00m"<br />
}</p>
<p>function prntok {<br />
        echo -e "\e[1;32m[ $1 ]\e[00m"<br />
}</p>
<p>sorry ()<br />
{<br />
        prnt "Caught SIGINT, cleaning up..."<br />
        if [ -f tempfile ]; then<br />
                rm -rf tempfile<br />
                prntok "Found and removed tempfile, exiting now"<br />
        else<br />
                prntok "tempfile not found, exiting..."<br />
        fi<br />
        exit 1<br />
}</p>
<p>function getip {<br />
ping -c1 -W1 -q $1 | grep PING | awk '{print $3}' |tr -d \(\)<br />
}</p>
<p>iplist="$(ifconfig | grep 'inet addr' | awk '{print $2}' | tr -d [a-z,:] | grep -v '127.0.0.1')"<br />
echo > tempfile<br />
for ip in $iplist; do<br />
echo $ip >> tempfile<br />
done</p>
<p>sites="$(awk '$1 == "ServerName" { print $2 }' /etc/httpd/conf.d/vhost_* | uniq)"</p>
<p>for site in $sites; do<br />
        if [ $dbg -gt 0 ]; then<br />
                prnt "DEBUG: Pinging $site..."<br />
        fi</p>
<p>        siteip=$(getip $site)<br />
        ison=$(grep -c $siteip tempfile)</p>
<p>        if [ $dbg -gt 1 ]; then<br />
                prntok "DEBUG: siteip = $siteip"<br />
        fi</p>
<p>        if [ $ison = 1 ]; then<br />
                if [ $dbg -gt 1 ]; then<br />
                        prntok "DEBUG: $site found!"<br />
                fi</p>
<p>                echo "http://$site"<br />
        else<br />
                if [ $dbg -gt 1 ]; then<br />
                        prnt "DEBUG: $site not found"<br />
                fi</p>
<p>        fi</p>
<p>done</p>
<p>rm -rf tempfile<br />
exit 0<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2009/09/if-sites-resolve-to-server-print-urls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QMail restart script</title>
		<link>http://seanp2k.com/2009/08/qmail-restart-script/</link>
		<comments>http://seanp2k.com/2009/08/qmail-restart-script/#comments</comments>
		<pubDate>Sun, 23 Aug 2009 13:51:25 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[clamav]]></category>
		<category><![CDATA[clamd]]></category>
		<category><![CDATA[cpanel]]></category>
		<category><![CDATA[freshclam]]></category>
		<category><![CDATA[interworx]]></category>
		<category><![CDATA[interworx-cp]]></category>
		<category><![CDATA[iworx]]></category>
		<category><![CDATA[qmail]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[spamassassin]]></category>
		<category><![CDATA[spamd]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=88</guid>
		<description><![CDATA[I oversee a few hundred Linux-based systems, and >99% of them run the typical QMail / ClamAV / SpamAssassin stack. I personally think QMail sucks, but I have written a script that usually fixes most issues (stuck queue, delayed mail, other strange issues). You could easily edit this to be compatible with cPanel-based servers, but [...]]]></description>
			<content:encoded><![CDATA[<p>I oversee a few hundred Linux-based systems, and >99% of them run the typical QMail / ClamAV / SpamAssassin stack.  I personally think QMail sucks, but I have written a script that usually fixes most issues (stuck queue, delayed mail, other strange issues).  You could easily edit this to be compatible with cPanel-based servers, but as it stands it&#8217;s written for InterWorx-CP and servers without a control-panel system.  Note that this needs BASH to run and won&#8217;t work properly due to the way the counter is incremented in regular POSIX &#8216;sh&#8217;.</p>
<p>Link: http://seanp2k.com/m.sh<br />
<more><br />
It is below:<br />
<code><br />
#!/bin/bash<br />
# ----- BEING DECLARE FUNCTIONS -----</p>
<p># prnt - formats and echos input<br />
function prnt {<br />
        echo -e "\e[1;32m[ $1 ]\e[00m"<br />
}</p>
<p># killproc - uses pidof to find process name then tries to kill COUNTER number of times.<br />
# Accepts $1 as process name and $2 as $<br />
PROCNAME=""</p>
<p>function killproc {<br />
        procname=$1<br />
        counter=0<br />
        pids="$(pidof "$procname")"<br />
        while [ "$pids" ] &#038;&#038; ((counter++ < $2)); do<br />
                if [ $counter -eq $2 ]; then<br />
                        echo -e "\e[1;31m[ Couldn't kill $procname, tried $2 times.  PID is $pids ]\e[00m"<br />
                else<br />
                        # -----  DEBUGGING - uncomment next line -----<br />
                         # ps -elf | grep -i $procname<br />
                        for pid in $pids; do<br />
                                echo -e "\e[1;36m[ $procname killed, PID $pid, try $counter/$2 ]\e[00m"<br />
                                pkill -9 $pid<br />
                        done<br />
                sleep 1<br />
                pids="$(pidof "$procname")"<br />
                echo<br />
                fi<br />
        done<br />
}</p>
<p># ----- END DECLARE FUNCTIONS -----<br />
# ----- BEING MAIN SUB -----</p>
<p>prnt "Reset local and remote delivery concurrency limits"<br />
echo 200 > /var/qmail/control/concurrencylocal<br />
echo 200 > /var/qmail/control/concurrencyincoming<br />
echo 200 > /var/qmail/control/concurrencyremote</p>
<p>prnt "Restart InterWorx-CP"<br />
/etc/init.d/iworx restart</p>
<p>prnt "Restart ClamAV &#038; SpamAssassin"<br />
/etc/init.d/clamd stop<br />
/etc/init.d/spamassassin stop</p>
<p>killproc spamd 5<br />
killproc clamd 5</p>
<p>/etc/init.d/clamd start<br />
/etc/init.d/spamassassin start<br />
prnt "Restart POP3"<br />
/etc/init.d/pop3 restart</p>
<p>prnt "Restart POP3-SSL"<br />
/etc/init.d/pop3-ssl restart</p>
<p>prnt "Restart IMAP4"<br />
/etc/init.d/imap4 restart</p>
<p>prnt "Restart IMAP4-SSL"<br />
/etc/init.d/imap4-ssl restart</p>
<p>prnt "Restart SMTP"</p>
<p>svc -d /service/send /service/smtp /service/smtp2<br />
/etc/init.d/smtp stop<br />
/etc/init.d/smtp status</p>
<p>if [ "$(pidof qmail-send)" ]; then<br />
        counter=11<br />
        echo -en "\e[1;32m[ Waiting for SMTP to stop: "<br />
        while [ "$(pidof qmail-send)" ] &#038;&#038; ((counter-- > 0)); do<br />
                echo -n "$counter.."<br />
                sleep 1<br />
        done<br />
        echo -e " ]\e[00m"<br />
fi</p>
<p>/etc/init.d/smtp status<br />
svc -k /service/send<br />
killproc qmail-send 5<br />
prnt "Force-send qmail message queue"<br />
svc -u /service/send<br />
svc -a /service/send<br />
svc -u /service/smtp /service/smtp2<br />
/etc/init.d/smtp start<br />
prnt "Please ensure that SMTP and send are up"<br />
/etc/init.d/smtp status<br />
/var/qmail/bin/qmqtool -s<br />
# ----- END MAIN SUB -----<br />
exit 0;</p>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2009/08/qmail-restart-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New improved MySQL Backup script</title>
		<link>http://seanp2k.com/2009/03/new-improved-mysql-backup-script/</link>
		<comments>http://seanp2k.com/2009/03/new-improved-mysql-backup-script/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 09:31:51 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=62</guid>
		<description><![CDATA[Auto-detects databases, has the temp file and backup file locations separated, purple colored real-time output, only logs important output, md5sums into a text file for databases, every filename uniquely hashed with month, day, year, hour, minute, and second, timestamps everything, uses bzip2 compression for smallest file sizes. #!/bin/bash # vars &#8211; no trailing slash please [...]]]></description>
			<content:encoded><![CDATA[<p>Auto-detects databases, has the temp file and backup file locations separated, purple colored real-time output, only logs important output, md5sums into a text file for databases, every filename uniquely hashed with month, day, year, hour, minute, and second, timestamps everything, uses bzip2 compression for smallest file sizes.</p>
<blockquote><p>#!/bin/bash</p>
<p># vars &#8211; no trailing slash please<br />
THEDATE=$(date +%m%d%y%H%M%S)<br />
BACKUPDIR=&#8217;/backups/mysql&#8217;<br />
TEMPDIR=&#8217;/backups/mysql/temp&#8217;<br />
LOGFILE=&#8221;$TEMPDIR/info-$THEDATE.txt&#8221;<br />
USER=root<br />
PASSWORD=password<br />
date &gt; $LOGFILE</p>
<p>date</p>
<p>echo -e &#8220;\e[1;35m[ " $(date +%H:%M:%S) "-- Starting MySQL Backup Script v0.3 by Seanp2k ]\e[00m"</p>
<p># magic<br />
DATABASES=$(mysql --user=$USER --password=$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database)</p>
<p>echo -e "\e[1;35m[ " $(date +%H:%M:%S) "-- Found" $(echo $DATABASES | wc -w) "databases:" $DATABASES "]\e[00m"</p>
<p># loop -- dump and hash<br />
for DB in $DATABASES; do</p>
<p>echo -en "\e[1;35m[ " $(date +%H:%M:%S)<br />
echo -n " -- Processing " $DB ".."<br />
mysqldump --user=$USER --password=$PASSWORD --databases $DB &gt; $TEMPDIR/$DB-$THEDATE.sql<br />
echo -n "..md5sum..."<br />
md5sum $TEMPDIR/$DB-$THEDATE.sql &gt;&gt; $LOGFILE<br />
echo -e "Done ]\e[00m"<br />
done</p>
<p># compress and clean<br />
echo -e "\e[1;35m[ " $(date +%H:%M:%S) "-- Creating Archive " $BACKUPDIR/mysql-THEDATE.tar.bz2 "]\e[00m"<br />
time tar -cvvjf $BACKUPDIR/mysql-$THEDATE.tar.bz2 $TEMPDIR/*.sql $TEMPDIR/info-$THEDATE.txt<br />
rm -rf $TEMPDIR/*.sql $TEMPDIR/info-$THEDATE.txt<br />
date<br />
echo -e "\e[1;35m[ " $(date +%H:%M:%S) "-- Finished ]\e[00m&#8221;</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2009/03/new-improved-mysql-backup-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keep a remote Winamp playing your newest music with a short bash script</title>
		<link>http://seanp2k.com/2009/01/keep-a-remote-winamp-playing-your-newest-music-with-a-short-bash-script/</link>
		<comments>http://seanp2k.com/2009/01/keep-a-remote-winamp-playing-your-newest-music-with-a-short-bash-script/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 11:48:56 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[remote]]></category>
		<category><![CDATA[rpc]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[winamp]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=47</guid>
		<description><![CDATA[I had a problem: I wanted my radio station to automagically play my newer music and update the stuff that it plays every day, yet keep enough older stuff that there is still some variety, especially if no new music gets discovered for a while. I&#8217;d need to find some way to keep the most [...]]]></description>
			<content:encoded><![CDATA[<p>I had a problem:  I wanted my radio station to automagically play my newer music and update the stuff that it plays every day, yet keep enough older stuff that there is still some variety, especially if no new music gets discovered for a while.  I&#8217;d need to find some way to keep the most recent 200 or so tracks playing on my station.</p>
<p>Let&#8217;s start by looking at what we have and what we have to do:<br />
Files on a Linux fileserver playing on a Windows server (via samba) in Winamp using EdCast to stream to sc_serv (Shoutcast) on a different Linux server in the DMZ.  Currently, I have the X: drive on the Windows server mapped to the Linux Fileserver.  Winamp re-scans the fileserver every 3 days for new music and adds it to the library, but I still have to manually go in and add new tracks to the playlist.</p>
<p>Some initial ideas and problems:<br />
-Use XML-RPC / SOAP from another music cataloging program that I currently use<br />
+I just really feel like there was an easier way to do what I wanted without going through all the trouble.</p>
<p>-Telling Winamp to [re]load the playlist: the Winamp API Uses C++&#8230;yuck&#8230;I don&#8217;t know or want to learn C++ just for this project.  Plus, DRY applies, someone HAS to have thought of this before.<br />
+Solution: httpQ, a simple http listener plugin for Winamp that uses a simple and easy to implement control scheme: simply call the right URL and Winamp does what you want.  Awesome. ( <a href="http://httpq.sourceforge.net/">http://httpq.sourceforge.net</a> )</p>
<p>-Finding files that have been modified recently, and if none have been modified in the time specified, keep looking until you find enough files<br />
<span id="more-47"></span><br />
So let&#8217;s look at what we&#8217;re going to do with this script:<br />
-Set up some variables for internal use and for how many tracks we want in our playlist<br />
-Loop through something to find our tracks and write them out to a file<br />
-Check that file to see if if has as many lines as we want (I know a better way to do this would be to just store it in memory and index it until you have enough, but on a modest p4 this executes in about 1 second in a directory with ~300GB files&#8230;YMMV but it wasn&#8217;t slow enough to justify re-writing it for me)<br />
-if it doesn&#8217;t, re-generate it and let some files that are a bit older get included as well<br />
-Tell Winamp to drop its current playlist<br />
-Tell Winamp to load our new playlist<br />
-Tell Winamp to play, just to make sure it&#8217;s playing&#8230;you don&#8217;t want to have dead air, even on the internet.</p>
<p>And finally, the script:</p>
<blockquote><p>#!/bin/bash</p>
<p>DAY=3<br />
#set the default to search for files 3 or less days old</p>
<p>CNT=0<br />
#initalize count&#8230;don&#8217;t really need to but it makes me feel better</p>
<p>DESIRED=200<br />
#how many files do you want (at least)?</p>
<p>until [ $CNT -ge $DESIRED ]; do<br />
#until the playlist has as many or more files than we specified, keep doing this over and over&#8230;probably should set some limit so it doesn&#8217;t go nuts if it has an error</p>
<p>find /foo/bar -mtime -&#8221;$DAY&#8221; -iname &#8220;*.mp3&#8243; -print | sed &#8216;s^/foo/bar/^X:\\files\\^&#8217; | tr &#8216;/&#8217; &#8216;\&#8217; &gt; /foo/bar/current.m3u<br />
#find files named *.mp3 in /foo/bar with a modified time of minus X days and echo the results&#8230;to sed which replaces /foo/bar with X:\Windows\Path&#8230;fix for converting slashes to<br />
#backslashes&#8230;sed also works but tr runs faster</p>
<p>CNT=$(wc -l /foo/bar/current.m3u | cut -d\  -f1)<br />
#count the lines of the playlist.  Note that I&#8217;m passing a space as the delimeter to cut, by escaping with a backslash then double space until the next flag,<br />
#which grabs column 1 (col2 is the filename, yick)</p>
<p>let DAY+=1<br />
#shorthand for day = day+1&#8230;won&#8217;t be used unless we loop again.<br />
done</p>
<p>wget -O &#8211; &#8211;quiet &#8220;http://windows:4800/delete?p=passwd&#8221;<br />
wget -O &#8211; &#8211;quiet &#8220;http://windows:4800/playfile?p=passwd&amp;file=X:\current.m3u&#8221;<br />
wget -O &#8211; &#8211;quiet &#8220;http://windows:4800/play?p=passwd&#8221;<br />
#the RPC calls to the Windows server.  Note that we&#8217;re telling wget to output to -&#8230;i.e. drop the output.<br />
#Also, be sure to double quote that URL.<br />
exit 0;<br />
#exit with no error code
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2009/01/keep-a-remote-winamp-playing-your-newest-music-with-a-short-bash-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple MySQL DB Backup script</title>
		<link>http://seanp2k.com/2008/08/simple-mysql-db-backup-script/</link>
		<comments>http://seanp2k.com/2008/08/simple-mysql-db-backup-script/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 22:55:16 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[back-up]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=20</guid>
		<description><![CDATA[MySQL has become an important part of most Web servers, especially over the last few years. With all those databases, the risk of corruption, intrustion, data loss, hardware failure, and lots of other factors necessitate automated backups. Luckily, backing up MySQL isn&#8217;t nearly as hard as it might sound. Actually, it&#8217;s only one command. But, [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL has become an important part of most Web servers, especially over the last few years.  With all those databases, the risk of corruption, intrustion, data loss, hardware failure, and lots of other factors necessitate automated backups.</p>
<p>Luckily, backing up MySQL isn&#8217;t nearly as hard as it might sound.  Actually, it&#8217;s only one command.  But, not many people have only one MySQL DB, and dumping all of them to a single file can be hard to parse should you only need to import one.  This is easily remedied by making a script run on cron to dump them all individually.</p>
<p>I set this script to run once a week, monday morning at 5am.  It generates a logfile as well, info.txt.sl, which contains the date, a list of files, and their MD5Sum.  Finally, it uses bzip2 to compress the files efficiently.  MD5Sums are critical in determining the integrity of the archive and to ensure the database has not been corrupted or altered since the snapshot was taken.<br />
<span id="more-20"></span><br />
Without further ado;</p>
<blockquote><p>#!/bin/bash</p>
<p>#grab only the month, day, and year.<br />
THEDATE=$(date +%m%d%y)</p>
<p>#full path for backup directory.  Make sure it is writable by the user you have cron run the script as.<br />
BACKUPDIR=&#8217;/mysqlbackup&#8217;</p>
<p>#full path for logfile.  Probably don&#8217;t change this.<br />
LOGFILE=&#8221;$BACKUPDIR/info.txt.sql&#8221;</p>
<p>#username to connect to the DB with<br />
USR=&#8217;root&#8217;</p>
<p>#password for above user.  Change this.  Those are single quotes, not backticks.<br />
PSWD=&#8217;MYSQL USER PASSWORD GOES HERE&#8217;</p>
<p>#toss the date into the logfile.  This is the system provided date.<br />
date &gt; $LOGFILE</p>
<p>#the actual dumps.  Make sure you change all the passwords.<br />
#to add another database, follow this format: (replace [DBNAME] with the database name)<br />
#mysqldump -u $USR -p$PSWD [DBNAME] &gt; $BACKUPDIR/[DBNAME]_$THEDATE.sql</p>
<p>mysqldump -u $USR -p$PSWD information_schema &gt; $BACKUPDIR/information_schema_$THEDATE.sql<br />
mysqldump -u $USR -p$PSWD mysql &gt; $BACKUPDIR/mysql_$THEDATE.sql</p>
<p>#MD5Sum the dumps and write that to the log.<br />
md5sum $BACKUPDIR/information_schema_$THEDATE.sql &gt;&gt; $LOGFILE<br />
md5sum $BACKUPDIR/mysql_$THEDATE.sql &gt;&gt; $LOGFILE</p>
<p>#bzip2 all the files, including the log.  Name the archive with the date.<br />
tar -cvvjf $BACKUPDIR/$THEDATE.tar.bz2 $BACKUPDIR/*.sql</p>
<p>#clean up the dumped files as they are already tar&#8217;d<br />
rm -rf $BACKUPDIR/*.sql</p></blockquote>
<p>Add that to a crontab to run as a user with write permission on the backup directory and however often you want.  Note that in its current form, it will overwrite the archive if you run it twice in one day.  You can simply modify the &#8220;THEDATE=$(date +%m%d%y)&#8221; string to put more info in there, such as &#8220;THEDATE=$(date +%m%d%y%H%M%S)&#8221; to make the files suffixed with something like &#8220;081308170651&#8243; (08th month, 13th day, 08th 2dig-year, 17th hour, 6th minute, 51st second).  This may be more reliable depending on how often you want to run the backup.</p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2008/08/simple-mysql-db-backup-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu Hardy Heron unofficial sources.list, enable root account (and su)</title>
		<link>http://seanp2k.com/2008/07/ubuntu-hardy-heron-unofficial-sourceslist-enable-root-account-and-su/</link>
		<comments>http://seanp2k.com/2008/07/ubuntu-hardy-heron-unofficial-sourceslist-enable-root-account-and-su/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 04:40:24 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=18</guid>
		<description><![CDATA[I recently installed Ubuntu for the first time in a while, since version 6 actually.  My normal laptop runs Debian Etch and hasn´t been updated in about 9 months due to the samba update breaking smbclient on my laptop and thus forcing me to not care too much about updates, but I recently acquired a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently installed Ubuntu for the first time in a while, since version 6 actually.  My normal laptop runs Debian Etch and hasn´t been updated in about 9 months due to the samba update breaking smbclient on my laptop and thus forcing me to not care too much about updates, but I recently acquired a 1000mhz PIII laptop with 384mb ram, wifi, DVD-ROM, 1400&#215;1050 screen 15¨ LCD (!)  and 30GB of hdd.  Not bad for free.  Anywho, I have this insatiable urge to run bleeding edge software (see openSUSE being always updated / broken on my web server and the deafault ubuntu software repos, although being some of the largest out of all the linux distros (debian probably coming in second) they still don´t have things like Adobe Flash Player.  Let´s fix that:<br />
<span id="more-18"></span></p>
<p>1.  Pop open your favorite terminal and ´su´ to root.  To enable su in ubuntu, do a</p>
<blockquote><p>
sudo passwd root
</p></blockquote>
<p>and type in a password for your root account, and please, for the love of security, don´t make it the same as your regular user password&#8230;all because sudo is a pain in the butt.</p>
<p>2.  Type:</p>
<blockquote><p>nano /etc/apt/sources.list</p></blockquote>
<p>3. Press Ctrl + O and change the filename to ´/etc/apt/sources.list.old´.  Press enter to save it.  Press ´y´ to save under a different name.</p>
<p>4. Scroll up to the top line using the arrow keys.  Make sure you go all the way to the top.  Mash down Ctrl+K to cut line&#8230;except we won´t be pasting it anywhere.</p>
<p>5. Paste the following into the file:</p>
<blockquote><p># /etc/apt/sources.list file for Ubuntu Hardy Heron 8.04.<br />
# Put together and tested by John Pyper, BaD_CrC on Freenode IRC.<br />
# Everything here works for me. Your success may vary.<br />
# This is a work in progress.</p>
<p>### [UBUNTU]<br />
# url: http://ubuntu.com/<br />
# http://ubuntu.osuosl.org/ is my mirror of choice due to speed and almost instant updates<br />
deb http://ubuntu.osuosl.org/ubuntu/ hardy main restricted universe multiverse<br />
deb http://ubuntu.osuosl.org/ubuntu/ hardy-updates main restricted universe multiverse<br />
deb http://ubuntu.osuosl.org/ubuntu/ hardy-backports main restricted universe multiverse<br />
deb http://ubuntu.osuosl.org/ubuntu/ hardy-proposed main restricted universe multiverse<br />
# get security updates from ubuntu security directly only<br />
deb http://security.ubuntu.com/ubuntu/ hardy-security main restricted universe multiverse</p>
<p>### [CANONICAL]<br />
# url: http://canonical.com/<br />
deb http://archive.canonical.com/ubuntu/ hardy partner<br />
deb http://archive.canonical.com/ubuntu/ hardy-updates partner<br />
deb http://archive.canonical.com/ubuntu/ hardy-backports partner<br />
deb http://archive.canonical.com/ubuntu/ hardy-proposed partner<br />
deb http://archive.canonical.com/ubuntu/ hardy-security partner</p>
<p>### [MEDIBUNTU]<br />
# url: http://medibuntu.org/<br />
deb http://packages.medibuntu.org/ hardy free non-free</p>
<p>### [WINE]<br />
# url: http://winehq.org/<br />
deb http://wine.budgetdedicated.com/apt/ hardy main</p>
<p>### [VIRTUALBOX]<br />
# url: http://virtualbox.org/<br />
# no hardy repo yet, this works fine with hardy. will update as it becomes available.<br />
deb http://virtualbox.org/debian/ gutsy non-free</p>
<p>### [MOBLOCK]<br />
# url: http://moblock-deb.sourceforge.net<br />
deb http://moblock-deb.sourceforge.net/debian/ hardy main</p>
<p>### [CORENOMINAL]<br />
# url: https://launchpad.net/~corenominal/<br />
# no hardy repo yet, this works fine with hardy. will update as it becomes available.<br />
deb http://ppa.launchpad.net/corenominal/ubuntu/ gutsy main restricted universe multiverse</p>
<p>### [GOOGLE]<br />
# url: http://google.com/linuxrepositories/<br />
deb http://dl.google.com/linux/deb/ stable non-free</p>
<p>### [VIDEOLAN]<br />
# url: http://videolan.org/<br />
deb http://nightlies.videolan.org/build/hardy-i386/arch ./</p>
<p>### [LXDE]<br />
# url: http://lxde.org/<br />
deb http://ppa.launchpad.net/lxde/ubuntu hardy main</p></blockquote>
<p>6. Press Ctrl+O again and change the name back to ´/etc/apt/sources.list´ and hit enter.  Press Y again to save under a different name.</p>
<p>7. Press Ctrl+X to exit GNU nano.</p>
<p>8. While still root, type:</p>
<blockquote><p>apt-get update</p></blockquote>
<p>and you should see a scroll of all the updates to your package list.  Now you can go back to using synaptic or aptitude and be able to select from quite a large range of packages.</p>
<p>Ooh, and one last step&#8230;<br />
9. Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2008/07/ubuntu-hardy-heron-unofficial-sourceslist-enable-root-account-and-su/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Check for failed SSHD authentication attempts in OpenSuse 10.3</title>
		<link>http://seanp2k.com/2008/07/check-for-failed-sshd-authentication-attempts-in-opensuse-103/</link>
		<comments>http://seanp2k.com/2008/07/check-for-failed-sshd-authentication-attempts-in-opensuse-103/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 04:21:57 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=16</guid>
		<description><![CDATA[Unlike Debian which uses the standard /var/log/sshd style logfile, OpenSuse uses the newer syslog-ng facility and is generally more annoying when trying to just parse a log file for some useful info.  However, it is not impossible, and it seems many users (including myself) were having a hard time finding where failed sshd login attempts [...]]]></description>
			<content:encoded><![CDATA[<p>Unlike Debian which uses the standard <em>/var/log/sshd</em> style logfile, OpenSuse uses the newer <em>syslog-ng</em> facility and is generally more annoying when trying to just parse a log file for some useful info.  However, it is not impossible, and it seems many users (including myself) were having a hard time finding where failed <em>sshd</em> login attempts get logged.  Webmin was not of much assistance in this area, nor was google.  I however did manage to eventually find, by using my <em>grip</em> function that I posted about earlier in <em>/var/log</em> to find this little nugget:<br />
<span id="more-16"></span></p>
<blockquote><p>cat /var/log/warn |grep sshd |grep failure |less</p></blockquote>
<p>You will probably want to make an alias out of that, like this:</p>
<blockquote><p>echo &#8220;alias sshfail=&#8217;cat /var/log/warn |grep sshd |grep failure |less&#8217;&#8221; &gt;&gt; ~/.bashrc</p></blockquote>
<p>Make sure to re-execute <em>bash</em> to re-load your .bashrc and apply the alias.  When you want to see who is trying to bruteforce your server, simply type <em>sshfail</em> and it will pop up a list of all the attempts.</p>
<p>Remember to always keep your <em>ssh</em> server as secure as possible to prevent attacks.  I have written a whitepaper on this which can be found <a href="securing_sshd.pdf">here</a> and will probably get its own post when time allows.</p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2008/07/check-for-failed-sshd-authentication-attempts-in-opensuse-103/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy but useful bash functions (grip and sshcp)</title>
		<link>http://seanp2k.com/2008/05/easy-but-useful-bash-functions-grip-and-sshcp/</link>
		<comments>http://seanp2k.com/2008/05/easy-but-useful-bash-functions-grip-and-sshcp/#comments</comments>
		<pubDate>Sat, 17 May 2008 06:09:00 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=13</guid>
		<description><![CDATA[If you&#8217;re like me and easily forget exact syntax of commands and don&#8217;t really feel like dedicating the necessary block of brain space reserved for the root user to memorization of exact syntax, I offer you these simple bash functions.  Toss them into your ~/.bashrc file for instant fun (protip: type bash to reload bash [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me and easily forget exact syntax of commands and don&#8217;t really feel like dedicating the necessary block of brain space reserved for the root user to memorization of exact syntax, I offer you these simple bash functions.  Toss them into your ~/.bashrc file for instant fun (protip: type <em>bash</em> to reload bash after you have added these to load them up without re-logging) or put them into <em>/etc/bash.bashrc</em> to apply them to all users using bash on your system.</p>
<p>The first function searches through the text of all the files in your current directory.  Very useful for, say, debugging a PHP script you didn&#8217;t write and can&#8217;t track down where that damn MySQL connect string actually <em>is</em>.</p>
<p><span id="more-13"></span></p>
<p>Usage: <em>grip <strong>[text]</strong></em></p>
<blockquote><p>function grip {<br />
grep -ir &#8220;$1&#8243; &#8220;$PWD&#8221;<br />
}</p></blockquote>
<p>Yes, it is VERY simple, however I believe you will find it is an indispensable tool for hunting stuff down and cutting the time searching by <em>at least</em> 9000 times.</p>
<p>The next script looks a bit more complex, partially because I commented it so you could see what is going on, partially because it&#8217;s so customizable.  It&#8217;s for running <em>scp</em> with preset variables, you could maybe make a few of these for different servers you use <em>scp</em> to send files to, again a big time-saver.  Note that this assumes that <em>scp</em> is in your $PATH.  If it isn&#8217;t, edit the final command that actually runs <em>scp</em> to whatever is relevant to your configuration.</p>
<p>Usage: <em>scp <strong>file [remotefile]</strong></em></p>
<blockquote><p>function sshcp {<br />
#ssh cp function by seanp2k<br />
FNAME=$1<br />
#the name of the file or files you want to copy<br />
PORTNUM=&#8221;22&#8243;<br />
#the port number for ssh, usually 22<br />
HOSTNAM=&#8221;192.168.1.1&#8243;<br />
#the host name or IP you are trying to ssh into<br />
if [ $2 ]<br />
then<br />
RFNAME=&#8221;:$2&#8243;<br />
else<br />
RFNAME=&#8221;:&#8221;<br />
fi<br />
#if you specify a second argument, i.e. sshcp foo.tar blah.tar,<br />
#it will take foo.tar locally and copy it to remote file bar.tar<br />
#otherwise, just use the input filename<br />
USRNAME=&#8221;root&#8221;<br />
#you should never allow root login via ssh, so change this username</p>
<p>scp -P &#8220;$PORTNUM&#8221; &#8220;$FNAME&#8221; &#8220;$USRNAME@$HOSTNAM$RFNAME&#8221;</p>
<p>}</p></blockquote>
<p>Whew.  You will have to configure this for it to work correctly, unless you want to log into 192.168.1.1 on port 22 with username &#8220;root&#8221; and copy files to root&#8217;s home directory.  I believe you can specify a different path in the second argument to <em>sshcp</em> assuming that the user you are logging in as has permission to write to that directory.  Example: <em>sshcp somefile.conf /etc/apache2/httpd.conf</em> .  Note that I have not tried this and I would not be surprised if it didn&#8217;t work.  Also note that <strong>it will overwrite the destination file without conformation</strong>.  You have been warned.</p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2008/05/easy-but-useful-bash-functions-grip-and-sshcp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Find all symbolic links recursively</title>
		<link>http://seanp2k.com/2008/05/find-all-symbolic-links-recursively/</link>
		<comments>http://seanp2k.com/2008/05/find-all-symbolic-links-recursively/#comments</comments>
		<pubDate>Sat, 10 May 2008 04:29:14 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://seanp2k.com/?p=8</guid>
		<description><![CDATA[I just (hopefully) finished debugging my SqueezeCenter install somehow adding ~300,000 files to my library&#8230;symbolic links.  While usually they are awesome and save time as typing cd /www is much easier than cd /usr/local/www/htdocs ha. So, to locate all symbolic links in the current directory and any directories under that: find */* -type l That [...]]]></description>
			<content:encoded><![CDATA[<p>I just (hopefully) finished debugging my SqueezeCenter install somehow adding ~300,000 files to my library&#8230;symbolic links.  While usually they are awesome and save time as typing</p>
<blockquote><p>cd /www</p></blockquote>
<p>is much easier than</p>
<blockquote><p>cd /usr/local/www/htdocs</p></blockquote>
<p>ha.</p>
<p>So, to locate all symbolic links in the current directory and any directories under that:</p>
<blockquote><p>find */* -type l</p></blockquote>
<p>That should do it!  Note that that is a lowercase &#8220;L&#8221; and not a &#8220;one&#8221;.  This should make it easier if you have a terrible recursion problem with some script following links and don&#8217;t feel like fixing the actual script, or in this case, a fairly large perl program AKA slimserver.</p>
]]></content:encoded>
			<wfw:commentRss>http://seanp2k.com/2008/05/find-all-symbolic-links-recursively/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
