Scriptifying Stuff: Installation for tarball of Mozilla Firefox on Linux

Spookyorange
8 min readApr 29, 2024

Hello there, me again, scriptifying the installation of another tarball installation.

Please note that I’ll keep it a bit more abstract here now that I already have an article that goes on detail about it

You might want to install Firefox this way, because your machine runs Ubuntu and you hate Snaps, or maybe your package manager doesn’t let you install it, or just don’t really want to install it yourself. You might have a lot of reasons to not do install it from package manager, and stick to a script to install it seperately from the system(kind of).

So let’s begin by researching and planning

Research and Plan

We begin by thinking about how to do this, let’s go over ’em fast step by step:

  1. Determine the link to download
  2. Observe the structure
  3. Plan about the execution

And the execution flow is gonna be determined after that, so let’s begin by observing, for this reasons, I go to Get Firefox page of the Mozilla Firefox, and look at the button’s link, then try out the link:

curl -o hello.tar.gz https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US

Aaaand, poof, nothing, what we get is some link, kind of. This is not what we want at all.

So I go ahead and try it with the follow command of curl:

curl -L -o heyhey.tar.bz2 https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US

Edit: Now it works with no problem whatsoever, so the real script is different, I guess Mozilla made some mistake before, IDK, but I have put so much effort into this tutorial, I actually want to keep the remaining part, the end product will be changed to the working one though, have fun. And now, we get something, but when I try to open it(in my gui for research purposes), I get greeted with an error!

Error says that it’s not an archive

Well, let’s change the extension to nothing and take a look at the file properties in Nautilus to see if we can find something?

We found out that It’s a Windows executable

Whoa?? Windows executable, but I installed Linux version, clearly stated in the HTTP request. So, I thought, like maybe it looks at the user agent and give the file accordingly. I’ve added my own user agent to see what happens:

curl -A "Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" -L -o heyhey.tar.bz2 https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US

And, nope, literally the same. This is a problem, a huge problem! You might say that it’s undoable and leave it here to install it manually(like a normal person). But, you see, I want to scriptify it, because I have fun doing it.

So continue on research, I’ve dealt with this kind of stuff before, how do I process, hmm. I know, whenever I try to install it, I get a redirection, this redirection takes me to the Windows version of the installation, but when I try to install from my Firefox, I get the Linux version(.tar.bz2). So, what if I merge these 2??

Let’s try that. After my request, I’ve saved the response and this is the response:

HTTP/1.1 302 Found
Cache-Control: max-age=60
Content-Type: text/html; charset=utf-8
Date: Fri, 26 Apr 2024 15:41:04 GMT
Location: https://download-installer.cdn.mozilla.net/pub/firefox/releases/125.0.2/win32/en-US/Firefox%20Setup%20125.0.2.exe
Content-Length: 136
Connection: keep-alive

<a href="https://download-installer.cdn.mozilla.net/pub/firefox/releases/125.0.2/win32/en-US/Firefox%20Setup%20125.0.2.exe">Found</a>.

Wow, look at that, we got a clean version here, I can just regex this and get the exact version: 125.0.2 right now. Let me just get the <a href…/> part only:

curl -o heeyy  https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US

This command is gonna output the <a href…/> part to the heeyy file with no problem, when I cat it:

<a href="https://download-installer.cdn.mozilla.net/pub/firefox/releases/125.0.2/win32/en-US/Firefox%20Setup%20125.0.2.exe">Found</a>.

Great! Now, let us grab the version from this guy:

grep -Po '/releases/\d+\.\d+\.\d+\/win32' heeyy | cut -d "/" -f 3

This should do it, we first use the power of Regex inside the grep and get the /releases/x.y.z/win32 and then take it’s output to cut, then we cut it by / and get the number 3(this was error and trial, never learned how it makes it and never will).

What I have here is the version! So let’s find out how to actually use this very valuable information.

I go to Get Firefox Page. Casually try to download it while I got my console open and look at the network tab, start download and then interrupt it, after all is done, I take the url which is:https://download-installer.cdn.mozilla.net/pub/firefox/releases/125.0.2/linux-x86_64/en-US/firefox-125.0.2.tar.bz2

That’s it, we got it now, 2 places with the versions, we can easily change them and get the files easily!

I go ahead and add to the script:

version=`grep -Po '/releases/\d+\.\d+\.\d+\/win32' heeyy | cut -d "/" -f 3`
url_we_want="https://download-installer.cdn.mozilla.net/pub/firefox/releases/$version/linux-x86_64/en-US/firefox-$version.tar.bz2"

Now, let me see if I can install it this way with curl, by adding another line:

curl -o hello.tar.bz2 $url_we_want

Let me run it to test it. And there it is, with all its glory:

The files of the tarballed Firefox

It was hell of a ride, but we automated this boring task in the end! On to the next research, how do we run it?

After a bit of a research, I found out that the firefox file is an executable, and when I run it, it just works. This is one of 3 parts, nice. Then I look for a .desktop file, but no luck in that area, so I need to create it myself, but a icon would be nice, so I search for it to find it in the glorious: browser/chrome/icons/default/default128.png (128 cuz it’s the highest, I feel like higher is better idk). So, we have 2 things we need and 1 part of the thing we want, which are: The files, the executable, and the icon(which is part of our .desktop file). 2.5, not bad at all!

Research is done here, let’s plan it!

Gather around, here’s the plan everyone:

  1. Get the package
  2. Extract it
  3. Take the extracted part to our safe place
  4. Clear out leftovers
  5. Make a new bin file in $HOME, for user to be able to use it from their terminal
  6. Create the desktop file and done!

This is it, real easy and literally the same plan as my other guide on scriptifying!

Let’s begin!

Execution

And here we are for the execution part, let’s go step by step:

Step 1: Get the package

We already did this in the research, because that this website works with JavaScript, we had to hack our way around, so yeah, this is what we came up with:

curl -o heeyy  https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US

sleep 3

if [ ! -f heeyy ]; then
echo "Make sure you have internet connection and try again."
echo "If you have internet connection, please report this issue on GitHub."
exit 1
fi

version=`grep -Po '/releases/\d+\.\d+\.\d+\/win32' heeyy | cut -d "/" -f 3`
url_we_want="https://download-installer.cdn.mozilla.net/pub/firefox/releases/$version/linux-x86_64/en-US/firefox-$version.tar.bz2"

curl -o hello.tar.bz2 $url_we_want

We try to get the version first, if we find it we use it to download the Linux version, if we can’t, the script will log some errors and exit negatively.

Step 2: Extract it

We got the package, we need to get it out of it’s package, it’s a tar.bz2 file, so we need the command for that exact format, I search around the web for it and find this:

tar -xvjf hello.tar.bz2

Tested it, works, done!

Step 3: Move extraction to the safe place

I got the folder I wanted, now I take it to the safe place of mine, which is $HOME/.tarball-installations, inside it, it will be named as firefox. Also I need to make sure safe place exists beforehand:

if [ ! -d $HOME/.tarball-installations ]; then
echo "Creating the $HOME/.tarball-installations directory for installation"
mkdir $HOME/.tarball-installations
fi

and then move the firefox codes to the safe place:

mv firefox $HOME/.tarball-installations/firefox

boom, done!

Step 4: Clean Up

We have got the stuff we wanted, now we need to get rid of the leftovers:

rm hello.tar.bz2
rm heeyy

yeah, that’s more like it!

Step 5: User’s executable

User may want to execute in their own way, so we add a bin to their $PATH, let’s go:

if [ ! -d ~/.local/bin/ ]; then
echo "~/.local/bin not found, creating it for you"
mkdir ~/.local/bin/
fi
touch ~/.local/bin/firefox
chmod u+x ~/.local/bin/firefox
echo "#!/bin/bash
~/.tarball-installations/firefox/firefox" >> ~/.local/bin/firefox

done and done!

Step 6: Desktop file

We need to set up a desktop file for the user to easily access it, we do so with:

touch ~/.local/share/applications/firefox.desktop
echo "
[Desktop Entry]
Name=Firefox
Keywords=web;browser;internet
Exec=$HOME/.tarball-installations/firefox/firefox %u
Icon=$HOME/.tarball-installations/firefox/browser/chrome/icons/default/default128.png
Terminal=false
Type=Application
MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https;
Categories=Network;WebBrowser;
Actions=new-window;new-private-window;profile-manager-window;
[Desktop Action new-window]
Name=Open a New Window
Exec=$HOME/.tarball-installations/firefox/firefox --new-window %u
[Desktop Action new-private-window]
Name=Open a New Private Window
Exec=$HOME/.tarball-installations/firefox/firefox --private-window %u
[Desktop Action profile-manager-window]
Name=Open the Profile Manager
Exec=$HOME/.tarball-installations/firefox/firefox --ProfileManager
" >> ~/.local/share/applications/firefox.desktop

Huh, big one, I’ve actually copied most of these stuff from their official desktop that I’ve found on my machine (:.

Glue ’em

For my last magic trick, I’m gonna glue them together!

Edit: Some parts are changed, because the official package has changed their system(or it was bugged before, so now we don’t really need version scraping or other sorts of stuff).

This is the variable-ized, and echo-added result:

#!/bin/bash

literal_name_of_installation_directory=".tarball-installations"
universal_path_for_installation_directory="$HOME/$literal_name_of_installation_directory"
firefox_installation_directory="$universal_path_for_installation_directory/firefox"
official_package_location="https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US"
tar_location="./hello.tar.bz2"
open_tar_location="./hello"
open_tar_application_data_location="$open_tar_location/firefox"

echo "Welcome to Firefox tarball installer, just chill and wait for the installation to complete!"

sleep 1

echo "Installing the latest package"
curl -L -o $tar_location $official_package_location

tar -xvjf $tar_location

echo "Installed and untarred successfully"

if [ ! -d $universal_path_for_installation_directory ]; then
echo "Creating the $universal_path_for_installation_directory directory for installation"
mkdir $universal_path_for_installation_directory
fi

mv firefox $firefox_installation_directory

echo "Firefox successfully moved to your safe place!"

rm -rf $open_tar_location
rm $tar_location

if [ ! -d ~/.local/bin/ ]; then
echo "~/.local/bin not found, creating it for you"
mkdir ~/.local/bin/
fi

touch ~/.local/bin/firefox
chmod u+x ~/.local/bin/firefox
echo "#!/bin/bash
$firefox_installation_directory/firefox" >> ~/.local/bin/firefox

echo "Created executable for your \$PATH if you ever need"

touch ~/.local/share/applications/firefox.desktop
echo "
[Desktop Entry]
Name=Firefox
Keywords=web;browser;internet
Exec=$firefox_installation_directory/firefox %u
Icon=$firefox_installation_directory/browser/chrome/icons/default/default128.png
Terminal=false
Type=Application
MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https;
Categories=Network;WebBrowser;
Actions=new-window;new-private-window;profile-manager-window;
[Desktop Action new-window]
Name=Open a New Window
Exec=$firefox_installation_directory/firefox --new-window %u
[Desktop Action new-private-window]
Name=Open a New Private Window
Exec=$firefox_installation_directory/firefox --private-window %u
[Desktop Action profile-manager-window]
Name=Open the Profile Manager
Exec=$firefox_installation_directory/firefox --ProfileManager
" >> ~/.local/share/applications/firefox.desktop

echo "Created desktop entry successfully"

sleep 1

echo "Installation is successful"

sleep 1

echo "Done, and done, have fun!"

sleep 1

exit 0

It’s way easier, because Mozilla fixed it while I was taking a break(thanks Mozilla ❤). But yeah, sometimes(like my Discord installation script) we are gonna need the method I’ve used here that no longer applies for this one.

Also we’re gonna need the uninstallation script too, because it’s not a safe thing to run an install script which has no uninstallation script for it, fortunately, it’s pretty easy:


git clone https://github.com/spookyorange/firefox-linux-install.git
cd firefox-linux-install
sh ./install.sh

And top it off with a creation of an open source repository, so that others may use it easily, create a nice README for it etc.. I did it so you don’t have to: This repo is the one I made!

This is it for today, have a good one.

Happy hacking!

--

--