Have you ever had the problem of installing a new Linux distro and scp
ing your config files to the home directory? Window/Desktop manager configs, .vimrc, .bashrc/.zshrc, and others. This problem is compounded with installations to multiple virtual machines, raspberry pis, etc. Luckily, there is a very handy tool that can make this process much easier and get your system up and running!
I recently found a tool called makeself while looking for an easy way to install patch files for my work. Makeself is an easy way to create self-extracting archives. Projects such as VirtualBox, Loki Software, and the Linux installer for Google Earth all use makeself to install their software. In this tutorial I’ll show you how to use makeself and a little bit of shell scripting to create an installer for your config files. This way, all you’ll need is one file that will extract the config files to the home directory. And best of all, this is very customizable. Use this tutorial as a starting point and build your install script however you’d like!
Setup
The first thing we’ll need to do is install makeself. There’s a package available on Ubuntu and the AUR for Arch. If you aren’t able to find the makeself package, it can also be pulled from GitHub at https://github.com/megastep/makeself. Here are the options depending on your situation:
# Ubuntu package
sudo apt-get install makeself
# AUR
pacaur -S makeself
# Pull from GitHub. git required.
git clone https://github.com/megastep/makeself
Collect config files
Next, let’s create a temporary directory that we will copy our config files to. This directory will mock our current $HOME
directory in the way we organize the files. This will be important when we extract these files on the next Linux system.
# Go to your home directory
cd ~/
# Create a directory for the config files.
mkdir config_files
# Copy your config files to the config_files/ directory.
cp .vimrc .bashrc .zshrc .xinitrc .toprc .tmux.conf config_files/
# If you have files in .config/, like an i3 config for example,
# make the directories before copying over the files to keep
# the same structure. The -p will create all parent directories
# if needed.
mkdir -p config_files/.config/i3
cp .config/i3/config config_files/.config/i3
# ... same for if you have a .vim directory. Use -r to recursively
# copy all files.
mkdir -p config_files/.vim/bundle
cp -r .vim/bundle/Vundle.vim config_files/.vim/bundle/
At this point, all config files should be in config_files/
.
Create the “payload”
We will now “tar” the config files. If you’re not familiar with the tool tar
, it is an archiving utility like what .zip files are. This archive will be the payload that we will extract onto our next system. Since this payload will be extracted on top of the home directory, it needs to be structured similar to our home directory.
tar -cvf payload.tar -C config_files/ .
If you’re not familiar with some of the flags, lets break them down.
-cvf
This c
reates the archive, prints v
erbose output and the desired f
ilename of the archive.
-C
This changes the current directory to be config_files/
.
This period is not a mistake. Once we change directory into config_files/
, we want to archive everything in that directory. The .
tells tar ‘this directory’.
We won’t add any compression flags since makeself takes care of compression when we package this all up in a later step.
Create staging directory
Next, we will create the directory that will hold our payload and install script. This is the directory that we’ll pass to makeself to compress and make executable.
# Be sure to be in your home directory
mkdir config_stage
# Copy the payload to this directory
cp payload.tar config_stage/
# Create an empty file that will be our install script
touch config_stage/install.sh
# And modify the file to be executable
chmod +x config_stage/install.sh
Write install script
This install script will extract the payload.tar
into the target’s home directory. It will be a very simple one line script. Depending on your use case, this script can be modified to fit your needs. It also doesn’t need to be a bash script. It could be a python script or even a rust binary; makeself doesn’t care as long as its executable and can be ran on the target system. But for simplicity, I will be writing it in bash.
config_stage/install.sh
#!/bin/bash
tar -xvf ./payload.tar -C "$HOME" &&
echo "Config files extracted successfully!"
The script will be written as if you are inside this staging directory.
Lets also go over that tar
command:
-xvf
This x
‘tracts the archive, with v
erbose output, for the f
ile ./payload.tar
-C
Again, this will set the current directory for tar
to be the home directory.
$HOME
This is an environment variable that stores the path of the currently logged in user’s home directory. For example: for the user bob, the $HOME directory would be /home/bob/
.
&&
This is to make sure that if the tar
command fails, all commands following will not be executed. This is very handy if the next commands require the command before it to succeed.
And thats, it! We are ready to use makeself to create our self-executing archive!
Run makeself
Now we will run makeself
against our config_stage/
directory. If you had pulled the GitHub version, change makeself
to the path to makeself.sh
in the git directory (ex: makeself/makeself.sh
)
makeself --sha256 ./config_stage my-configs-installer.run "My config files installer" ./install.sh
Here’s an breakdown of the command:
--sha256
This tells makeself to add a sha256 hash of the contents to its integrity check. Integrity checking is very important because we don’t want to have any corrupted files. If there is a problem transferring to another system and a part of the file failed to be sent, makeself will make sure to check and let you know.
./config_stage
is this directory to archive that will be extracted to a temporary directory on the system.
my-configs-installer.run
is the name of the executable that makeself will create. This can be any name you’d like.
"My config files installer"
This is the label for the executable. It also can be anything you’d like.
./install.sh
This is the install script we wrote to be executed after the config_stage/
is extracted to a temporary directory. We wrote this with a ./
as if we were in the config_stage/
directory.
The output should be similar to this and a new file my-configs-installer.run
will be in your home directory!
Header is 588 lines long
About to compress 4460 KB of data...
Adding files to archive named "my-configs-installer.run"...
./
./payload.tar
./install.sh
CRC: 2272251193
SHA256: 710b5c0e2b9c6b3b6bcd42274427ac47487f98afab088626eb472c72bd37e778
MD5: 03c9bde4560f41d7de3cd0237fd0d38c
Self-extractable archive "my-configs-installer.run" successfully created.
Executing on target system
When executed on the target system (by entering ./my-configs-installer.run
), it will first extract config_stage/
to a temporary directory in /tmp/
. Then it will run the ./install.sh
that will extract payload.tar
to the home directory. Once the script has finished, everything in the temporary directory will be deleted. Its that simple!
This executable file can be sent to any system you’d like to install your config files to. But the great thing is, its potential is endless. If there are other things that you do repetitively when setting up a new system, you can just add it to the install.sh script! No more having to do all of it by hand!
Makeself has more features that you might have fun playing with. To learn more you can just run makeself --help
.
Other helpful commands
The executable comes with a few helpful commands built in automatically. Here’s a few command examples:
–help
Makeself version 2.4.0
1) Getting help or info about ./my-configs-installer.run :
./my-configs-installer.run --help Print this message
./my-configs-installer.run --info Print embedded info : title, default target directory, embedded script ...
./my-configs-installer.run --lsm Print embedded lsm entry (or no LSM)
./my-configs-installer.run --list Print the list of files in the archive
./my-configs-installer.run --check Checks integrity of the archive
2) Running ./my-configs-installer.run :
./my-configs-installer.run [options] [--] [additional arguments to embedded script]
with following options (in that order)
--confirm Ask before running embedded script
--quiet Do not print anything except error messages
--accept Accept the license
--noexec Do not run embedded script
--keep Do not erase target directory after running
the embedded script
--noprogress Do not show the progress during the decompression
--nox11 Do not spawn an xterm
--nochown Do not give the extracted files to the current user
--nodiskspace Do not check for available disk space
--target dir Extract directly to a target directory (absolute or relative)
This directory may undergo recursive chown (see --nochown).
--tar arg1 [arg2 ...] Access the contents of the archive through the tar command
-- Following arguments will be passed to the embedded script
–check
Verifying archive integrity... 100% SHA256 checksums are OK. 100% MD5 checksums are OK. All good.
–info
Identification: My config files installer
Target directory: config_stage
Uncompressed size: 4460 KB
Compression: gzip
Date of packaging: Sun Sep 2 22:25:03 PDT 2018
Built with Makeself version 2.4.0 on linux-gnu
Build command was: /usr/bin/makeself
"--sha256"
"./config_stage"
"my-configs-installer.run"
"My configs installer"
"./install.sh"
Script run after extraction:
./install.sh
config_stage will be removed after extraction
Loading Likes...
This guide helped me. I have implemented the sequence of steps in a script that allows you to easily manage the whole process. github.com/FabrizioCafolla/self-extractable-archives-linux
I’m glad to hear this guide was helpful! š
is there any example with –append options ?