Bash Self-Extracting Script
- The Payload
- The Decompression Script
- The Builder Script
jeff:~$ mkdir -vp installer/payload mkdir: created directory `installer' mkdir: created directory `installer/payload' jeff:~$ cd installer/ jeff:~/installer$The Payload The payload directory will contain....just that, the payload of your installer. This is the location where you'll put all your tar files, scripts, binaries, etc that you'll want installed onto the new system. For this example I have a tar file containing some text files that I'll want to install into a folder that I create into my home directory. Here is the listing of the tar file.
jeff:~$ tar tvf files.tar -rw-r--r-- jeff/jeff 40 2007-12-06 07:53 ./File1.txt -rw-r--r-- jeff/jeff 92 2007-12-06 07:55 ./File2.txt jeff:~$Now we must create the installation script that will handle the payload. This script contains any actions that you'd wish to be performed on the installation system, make directories, uncompress files, run system commands, etc. For the example I will create a directory and untar the files into it.
#!/bin/bash echo "Running Installer" mkdir $HOME/files tar ./files.tar -C $HOME/filesNow that we have filled our payload directory with all the files we'd like to install and created the installation script to the the files in their correct location, our directory structure should look like this:
jeff:~$ find installer/ installer/ installer/payload installer/payload/installer installer/payload/files.tar jeff:~$The Decompression Script The Decompression Script does most of the work. The compressed archive of your payload directory will actually be appended onto this script. When ran, the script will remove the archive, decompress it and execute the install script we had created in the previous section.
#!/bin/bash
echo ""
echo "Self Extracting Installer"
echo ""
export TMPDIR=`mktemp -d /tmp/selfextract.XXXXXX`
ARCHIVE=`awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' $0`
tail -n+$ARCHIVE $0 | tar xzv -C $TMPDIR
CDIR=`pwd`
cd $TMPDIR
./installer
cd $CDIR
rm -rf $TMPDIR
exit 0
__ARCHIVE_BELOW__
Ok, now lets go through this script step by step. After the bit of printout
at the begining, the first real line of work creates a temporary directory
for us to decompress our payload into initially before we install it.
export TMPDIR=`mktemp -d /tmp/selfextrac.XXXXXX`The
-dflag tells mktemp to create a directory rather than a file. The parameter at the end,
/tmp/selfextract.XXXXXXis a template of the name of the directory we are going to create. The X's are replaced with random characters to generate a random name, just incase we happen to be installing two things at the same time. The next line in the script,
ARCHIVE=`awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' $0`
find the line number where the archive starts in the script. The first
parameter given to awk /^__ARCHIVE_BELOW__/tells it to search for a regular expression "A line starting with the characters '__ARCHIVE_BELOW__'". Each line is read and until the regular expression is satisfied. The next parameter
{print NR + 1; exit 0; } tells
awk to print out the number of records (number of lines read) plus 1, then
quit. The third parameter $0is the first argument when running this script, which happens to be the script's name ($0 = ./decompress). We will now seperate the archive from the script and decompress it into the temporary directory we have created.
tail -n+$ARCHIVE $0 | tar xzv -C $TMPDIRtail prints out the end of a file. The parameter
-n+$ARCHIVEtells tail to start at line number we just read in the previous command, and print til the end of the file.
$0again is the name of this script file. This output is then piped to tar where it is
zungzipped, and
xunarchived into
-C $TMPDIRthe temporary directory. The next section, we remember our current directory,
CDIR=`pwd`and step into the temporary directory
cd $TMPDIR. From here we run the script we created in the Payload section. After the script has been executed, we revert back to our previous directory
cd $CDIRand remove the temporary directory
rm -rf $TMPDIRThe last two lines in this script are very important. First the line
exit 0causes the script to stop executing. If we forget this line BASH would try to execute the binary archive attached at the bottom and would cause problems. The very last line
__ARCHIVE_BELOW__tells awk that the binary archive starts on the next line. Make sure that this is the last line, no extra empty lines below this one. Now that we have finished creating the Decompression script our directory should looke like this:
jeff:~$ find installer/ installer/ installer/build installer/payload installer/payload/installer installer/payload/files.tar installer/decompress jeff:~$The Builder Script The last section of this installer is the script that builds the self-extracting script. This script compresses the payload and then adds the decompresion script to the archive.
#!/bin/bash
cd payload
tar cf ../payload.tar ./*
cd ..
if [ -e "payload.tar" ]; then
gzip payload.tar
if [ -e "payload.tar.gz" ]; then
cat decompress payload.tar.gz > selfextract.bsx
else
echo "payload.tar.gz does not exist"
exit 1
fi
else
echo "payload.tar does not exist"
exit 1
fi
echo "selfextract.bsx created"
exit 0
This script archives the payload directory
tar cf ../payload.tar ./*and compresses it using gzip
gzip payload.tar. Next the script concatenates the decompress script with the compressed payload
cat decompress payload.tar.gz > selfextract.bsx. With all the scripts completed our directory should look like this:
jeff:~$ find installer/ installer/ installer/build installer/payload installer/payload/installer installer/payload/files.tar installer/decompress jeff:~$Test it out Now that we have created everything, we can run the scripts and test it all out. Firstly run the build script. Your output should look as follows:
jeff:~/installer$ ./build selfextract.bsx created jeff:~/installer$ ls build decompress payload payload.tar.gz selfextract.bsx jeff:~/installer$Now we have our bash script with the archive attached (selfextract.bsx). Run this script and you should see the following output:
jeff:~/installer$ ./selfextract.bsx Self Extracting Installer ./files.tar ./installer Running Installer ./File1.txt ./File2.txt jeff:~/installer$ find /home/jeff/files /home/jeff/files /home/jeff/files/File1.txt /home/jeff/files/File2.txt jeff:~/installer$If you would like the installer to install something else, just place the files in the payload directory and modify the installer script to perform the proper action.
Software Engineer in Marshalltown, IA BB PIN: 21C3344D www.biffengineering.com
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- Reply to comment | Linux Journal
4 hours 20 min ago - Nice article, thanks for the
15 hours 35 sec ago - I once had a better way I
20 hours 46 min ago - Not only you I too assumed
21 hours 3 min ago - another very interesting
22 hours 56 min ago - Reply to comment | Linux Journal
1 day 50 min ago - Reply to comment | Linux Journal
1 day 7 hours ago - Reply to comment | Linux Journal
1 day 8 hours ago - Favorite (and easily brute-forced) pw's
1 day 9 hours ago - Have you tried Boxen? It's a
1 day 15 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
A sample file
I would much easier to follow if there is a sample file, which is self extractable.
need a calrification
Hi
The statement " We will now seperate the archive from the script and decompress it into the temporary directory we have created. tail -n+$ARCHIVE $0 | tar xzv -C $TMPDIR
tail prints out the end of a file. The parameter -n+$ARCHIVE tells tail to start at line number we just read in the previous command, and print til the end of the file. "
How does this work exactly? can you please explain
it got fixed
i was running in a different folder.now it is running fine.
Small correction
Hey,
This is great! The only problem I had was using the installer script, running the line you have here:
tar ./files.tar -C $HOME/filesgave me errors. Using
tar xf ./files.tar -C $HOME/filesmade everything work fine. Thanks again!
Terms of Use, small imprvement
Hello,
Just to make sure, can parts of the example script be used under the terms of the GPL?
By the way, the script is working well, but I recommend quotes around $0: "$0" as otherwise filenames with spaces or other curious characters would break it.
Sure thing, I guess I see it
Sure thing, I guess I see it as Public Domain but I guess you'd just have to double check with LJ to make sure they don't retain rights on anything but i can't image they would.
Software Engineer in Marshalltown, IA
BB PIN: 21C3344D
www.biffengineering.com