Monthly Archives: December 2019

Self-extracting Shell Script

Self-extracting executables are a commonplace in Windows. Can it be or something like it be created in Linux, as well? If the question is CAN it be done for Linux, the answer to most “can” questions in open source world is a “yes”. But one does not need to be a copycat of Windows, when better things can be done in Linux – a self-extracting Shell Script.

For that, we just need to write a shell script, say This script will take the directory to be self-extracted and output the self-extracting shell script. But how does this self-extracting shell script work? Basically, there are two parts in this script: 1) the bottom one containing the compressed tar of the directory to be self-extracted, and 2) the top one containing the shell script to extract the bottom part. So, when one runs this shell script, it would run the top part extracting the bottom part. These two parts are demarcated by a unique marker for the top part to identify its bottom. Here is how a typical self-extracting shell script will look like with TGZ_CONTENT as the unique marker:


echo -n "Extracting script contents ... "
start_line_of_tar=$((`grep -an "^TGZ_CONTENT$" $0 | cut -d: -f1` + 1))
tail -n+${start_line_of_tar} $0 | tar zxf -
echo "done"
exit 0

The grep-cut pair extracts the line number of this script having TGZ_CONTENT, and then 1 is added to it to get the start_line_of_tar. Then, tail-tar pair extracts the tar, starting from start_line_of_tar till the end of the shell script file. The “exit 0” is important to stop the script execution after its top part is executed, as the bottom part is not really a script.

Now, here’s the script to generate the above self-extracting shell script:


if [ $# -ne 2 ]
	echo "Usage: $0 <directory_to_package> <self_extracting_script_file>"
	exit 1


cat > ${script} <<SCRIPT_TOP

echo -n "Extracting script contents ... "
start_line_of_tar=\$((\`grep -an "^TGZ_CONTENT$" \$0 | cut -d: -f1\` + 1))
tail -n+\${start_line_of_tar} \$0 | tar zxf -
echo "done"
exit 0
tar zcf - ${directory} >> ${script}

chmod +x ${script}

The two SCRIPT_TOP above are the delimiters for here-document (content from here) to be put into the generated shell script file. The tar line after that is to add the bottom content of the script. Notice the \ before the $ in the here-document, so as to not evaluate those in this script, but output verbatim into the self-extracting shell script.

Assuming an existing directory XYZ to be packaged into the self-extracting shell script, this script could be run as follows:

$ ./ XYZ

And running the shell script would extract back the XYZ directory, thus becoming a self-extracting shell script.

   Send article as PDF