Wibbly Stuff

How to Add Auto-Update to Your Bash Script

It was the time when I was developing my Fedora Utils script and wished to add autoupdate to it. It was not difficult. But certainly I had no clue about what to do. I didn't want to make another text file with update details on every new release and upload. I just wanted the process should be automatic. I asked in different forums, but no one could give an answer. But at last I did it! And I became the happiest man on the earth thereafter:)

So, the thing you need is the RSS feed of your Program Updates (Limited to the last update only). If you use Sourceforge to host your script, then you are lucky. So let's take a look at the update function of Fedora Utils,
function Update()
{
echo -e $BLUEBOLD"Checking Update"$ENDCOLOR
curl -s -o update http://sourceforge.net/api/file/index/project-id/504600/mtime/desc/limit/1/rss
latest=$(grep "guid" update | sed -e 's/^[ \t]*//' | cut -c77-93)
vdir=$(grep "guid" update | sed -e 's/^[ \t]*//' | cut -c59-73)
current=fedorautils-$VERSION
rm update
if [ $latest = $current ]; then
echo -e $GREEN"Fedora Utils is Up-to-date"$ENDCOLOR
elif [[ $latest < $current ]]; then
echo -e $YELLOW"How come you are using a newer version than the latest?"$ENDCOLOR
else
if [ $AUTOUPDATE = "ON" ]; then
echo -e $BLUE"Update found. Downloading Update..."$ENDCOLOR
curl -s -o $HOMEDIR/$latest http://master.dl.sourceforge.net/project/fedorautils/$vdir/$latest
if [ -e $HOMEDIR/$latest ]; then
chown $USER $HOMEDIR/$latest
chmod a+x $HOMEDIR/$latest
zenity --info --title="Update Available" --text="An updated version of Fedora Utils has been automatically downloaded and saved to $HOMEDIR/$latest. Please use that script instead."
Complete
else
echo -e $RED"Update failed"$ENDCOLOR
fi
else
echo -e $YELLOW"An update to Fedora Utils is available. It might contain new features and bug fixes. You are recommended to use the new version instead. Visit http://fedorautils.sf.net for details."$ENDCOLOR
fi
fi
}



The first part curl -s -o update http://sourceforge.net/api/file/index/project-id/504600/mtime/desc/limit/1/rss downloads the latest version RSS feed and saves it as a file named "update".

So let's take a closer look at the update file. I'm posting a small part as the whole file would be longer.
<title><![CDATA[/fedorautils-1.5/fedorautils-1.5.9]]></title>
<link>http://sourceforge.net/projects/fedorautils/files%2Ffedorautils-1.5%2Ffedorautils-1.5.9/download</link>
<guid>http://sourceforge.net/projects/fedorautils/files%2Ffedorautils-1.5%2Ffedorautils-1.5.9/download</guid>
<description><![CDATA[/fedorautils-1.5/fedorautils-1.5.9]]></description>
<pubDate>Mon, 22 Aug 2011 07:26:17 +0000</pubDate>
<files:sf-file-id xmlns:files="http://sourceforge.net/api/files.rdf#">4831249</files:sf-file-id>
Now, we see that the link between the <guid> tags contains the link to latest version. We will use grep to extract that specific line from the file. Note that the link between the <link> tags also contains the link to latest version, but there are more than one lines with the <link> tags inside the file. So we won't choose it.

So using "grep", we extract that line with the command grep "guid" update.

Now, that line would contain spaces and tabs along with the link. So we remove those unneeded spaces and tabs with "sed" and the command sed -e 's/^[ \t]*//'. Let's pipe the too commands to make "sed" work on the output given by "grep".
grep "guid" update | sed -e 's/^[ \t]*//'

Now what we get would be http://sourceforge.net/projects/fedorautils/files%2Ffedorautils-1.5%2Ffedorautils-1.5.9/download. But it is not the download link, instead a link to the download webpage. The part which is fedorautils-1.5%2Ffedorautils-1.5.9 tells us that the updated script is named as fedorautils-1.5.9 and is inside the folder fedorautils-1.5. So that's enough information to make the download link out of it.

We will extract the file name and folder name by counting the characters before and after it. My versioning system is so that the name with version always has the same no. of characters. So this makes our work easy. We will use the "cut" program for this purpose.

The lines below will do all text processing, extract the file name and folder name and assign them to variables "latest" and "vdir" respectively.
latest=$(grep "guid" update | sed -e 's/^[ \t]*//' | cut -c77-93)
vdir=$(grep "guid" update | sed -e 's/^[ \t]*//' | cut -c59-73)
Now we have to make the link out of it! Not too difficult. It would be http://master.dl.sourceforge.net/project/fedorautils/$vdir/$latest. Here "fedorautils" would be the project name (unix name) of your project and $vdir and $latest are the variables which will represent the folder and file names respectively.

So done! the line curl -s -o $HOMEDIR/$latest http://master.dl.sourceforge.net/project/fedorautils/$vdir/$latest will download the latest version automatically!

The other commands you see provide additional functionality. You only need to know what I explained to implement it in your script in your way. Sure, there are many more methods, might be easier and more accurate. But it's what I could think of. Please test and if you liked it, then Enjoy!