Skip to content

Instantly share code, notes, and snippets.

@ruario
Last active March 7, 2017 05:32
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ruario/ace4fb780216aa28d922 to your computer and use it in GitHub Desktop.
Extracts an Opera Debian package and installs it into /usr/local. An uninstall script is also created and installed as well. Upgrades work if you used this script to install a previous version. Completely unofficial and unsupported by Opera Software.

Disclaimer: I wrote this script for my own personal usage. It is not officially supported by Opera Software.

Whilst Opera currently only provide .deb packages, it is possible to install Opera on different distros. This install script automates the process.

If you don't already have the script, fetch it like so:

git clone https://gist.github.com/ace4fb780216aa28d922.git

To install the latest stable release, issue:

sudo sh install-opera.sh

To install the latest beta release, issue:

sudo sh install-opera.sh --beta

To install the latest developer release:

sudo sh install-opera.sh --developer

Alternatively you can install a specific build like so:

sudo sh install-opera.sh opera-stable_26.0.1656.32_amd64.deb

After install, you may need to re-login to your desktop environment before Opera is detected.

Note: A script to uninstall Opera is also placed on your system, to aid removing Opera later, should you wish to.

If you would like to ensure that Opera developer is automatically kept up to date, move the script to /usr/local/bin and make it executable:

sudo mv install-opera.sh /usr/local/bin/install-opera
sudo chmod +x /usr/local/bin/install-opera

You could then add the following to root's crontab:

00 18 * * 1-5 /usr/local/bin/install-opera --stable >/dev/null 2>&1

This would execute the script once a day at 18:00 (6pm), every Monday through Friday.

If you would like to schedule the script to run at different times, or would like to log the output and/or errors, read one of the many crontab guides found on the internet.

Note: You should not run this script more once per day, since we never release so frequently. Hammering Opera servers with requests could get your IP address banned and you would then receive no updates. In any case, If you ever notice that a new Opera is out and the script has not yet run, simply issue install-opera --stable manually to trigger an update right away.

#!/bin/sh
available () {
command -v "$1" >/dev/null 2>&1
}
updatedbs () {
# Setup menu entries
if available update-desktop-database; then
update-desktop-database -q /usr/local/share/applications
fi
# Setup icons
touch -c /usr/local/share/icons/hicolor
if available gtk-update-icon-cache; then
gtk-update-icon-cache -tq /usr/local/share/icons/hicolor
fi
}
# Uninstall function to be used by the removal script
removefiles () {
while read f; do
# '-e' alone would not find broken symlinks
if [ -e "$f" -o -h "$f" ]; then
if [ -d "$f" ]; then
if ! ls -A "$f" | grep -q ^; then
# Don't remove a symlink pointing to a directory, as it could have
# been created by the user or the distribution
if [ ! -h "$f" ]; then
rmdir -v "$f"
fi
fi
else
rm -v "$f"
fi
fi
done
} #
# Checks if the same Opera version is already installed
checkversion () {
if [ -e "/usr/local/lib$LIBDIRSUFFIX/$(echo $OPERA_STREAM | sed 's/\-stable//')/VERSION_$OPERA_VERSION" ]; then
echo "$OPERA_STREAM ($OPERA_VERSION) is already installed; exiting"
exit 0
fi
}
# Binutils is needed for this script to run
if ! available ar; then
echo "You must install GNU Binutils to use this script" >&2
exit 1
fi
# Quit if you can't write to /usr/local
if [ ! -w "/usr/local" ]; then
echo "You do not have write permission to /usr/local" >&2
echo "Re-run this script as root or prefaced with sudo, e.g." >&2
echo " \$ sudo $0 $@" >&2
exit 1
fi
# Check if this is being run as a self extractor
if [ -z "$1" ]; then
if [ $(sed '1,/^exit$/d' "$0" | head -n 1 | wc -l) = "1" ]; then
OPERA_DEB=$(mktemp -t opera-deb.XXXXXX)
sed '1,/^exit$/d' "$0" > "$OPERA_DEB"
DESTROY_DEB=Y
fi
fi
# Check if automatic download has been selected
while [ 0 ]; do
if [ "$1" = "-d" -o "$1" = "--developer" ]; then
OPERA_STREAM=opera-developer
DESTROY_DEB=Y
shift 1
elif [ "$1" = "-b" -o "$1" = "--beta" ]; then
OPERA_STREAM=opera-beta
DESTROY_DEB=Y
shift 1
elif [ "$1" = "-s" -o "$1" = "--stable" ]; then
OPERA_STREAM=opera-stable
DESTROY_DEB=Y
shift 1
else
break
fi
done
# Run some checks to see if a proper package has been selected
if [ -z "$DESTROY_DEB" -a -n "$1" ]; then
if ! echo "$1" | grep -q 'opera.*\.deb$'; then
echo "$1 is not named like an Opera Debian package" >&2
exit 1
fi
if [ -r "$1" ]; then
OPERA_DEB="$1"
DESTROY_DEB=N
OPERA_AUTO_FETCH=N
fi
fi
# Extract information from control file
if [ -n "$OPERA_DEB" ]; then
OPERA_STREAM_VERSION_DEBARCH=$(ar -p "$OPERA_DEB" control.tar.gz | tar -xzOf- ./control | sed -n 's/^Package: //p;s/^Version: //p;s/^Architecture: //p')
if [ -z "$OPERA_STREAM_VERSION_DEBARCH" ]; then
echo "Could extract the package name and architecture from the control file" >&2
exit 1
else
OPERA_STREAM=$(echo $OPERA_STREAM_VERSION_DEBARCH | cut -d' ' -f1)
OPERA_VERSION=$(echo $OPERA_STREAM_VERSION_DEBARCH | cut -d' ' -f2)
DEBARCH=$(echo $OPERA_STREAM_VERSION_DEBARCH | cut -d' ' -f3)
fi
# Set the architecture
case "$DEBARCH" in
amd64) ARCH=x86_64; LIBDIRSUFFIX="64" ;;
*) ARCH=$DEBARCH; LIBDIRSUFFIX="" ;;
esac
checkversion
else
OPERA_STREAM=${OPERA_STREAM:-opera-stable}
DESTROY_DEB=Y
# Set architecture information
ARCH=$(uname -m | sed 's/i.86/i386/')
case "$ARCH" in
x86_64) DEBARCH=amd64; LIBDIRSUFFIX="64" ;;
i386) DEBARCH=$ARCH; LIBDIRSUFFIX="" ;;
*) echo "The architecture $ARCH is not supported." >&2 ; exit 1 ;;
esac
# Make sure we have wget or curl
if available wget; then
SILENT_DL="wget -qO-"
LOUD_DL="wget"
DL_OUTPUT="-O"
elif available curl; then
SILENT_DL="curl -s"
LOUD_DL="curl"
DL_OUTPUT="-o"
else
echo "Install wget or curl" >&2
exit 1
fi
# Work out the latest Opera version
OPERA_VERSION=$($SILENT_DL http://deb.opera.com/opera/dists/stable/non-free/binary-$DEBARCH/Packages.gz | gzip -d | grep -A1 -x "Package: $OPERA_STREAM" | sed -n "/Version/s/.* //p")
# Error out if $OPERA_VERISON is unset, e.g. because previous command failed
if [ -z "$OPERA_VERSION" ]; then
echo "Could not work out the latest version of $OPERA_STREAM for $ARCH; exiting" >&2
exit 1
fi
checkversion
OPERA_DEB=$(mktemp -t opera-deb.XXXXXX)
$LOUD_DL http://deb.opera.com/opera/pool/non-free/o/$OPERA_STREAM/${OPERA_STREAM}_${OPERA_VERSION}_${DEBARCH}.deb $DL_OUTPUT $OPERA_DEB
if ! [ "$?" = 0 ]; then
echo "Download failed!" >&2
exit 1
fi
fi
# If an old Opera is already installed, remove it first
UNINSTALL_OPERA_SCRIPT=/usr/local/bin/remove-$OPERA_STREAM
if [ -x "$UNINSTALL_OPERA_SCRIPT" ]; then
echo "Removing previously installed Opera first"
sleep 1
. "$UNINSTALL_OPERA_SCRIPT"
fi
# Stop the script as soon as there is a problem
set -eu
# Extract files from the Debian package to a temporary location
OPERA_FILES=$(mktemp -d -t opera-files.XXXXXX)
printf "\nUncompressing Opera ...\n"
ar p "$OPERA_DEB" data.tar.xz | xz -d | tar -xf- -C "$OPERA_FILES" \
--transform="s,^\./usr,./usr/local,;s,/lib/${ARCH}-linux-gnu,/lib$LIBDIRSUFFIX," \
--exclude="./usr/share/lintian" --exclude="./usr/share/menu"
# Create the first part of the uninstall script
mkdir -p "$(dirname $OPERA_FILES/$UNINSTALL_OPERA_SCRIPT)"
sed -n '1,/^} #$/p' "$0" > "$OPERA_FILES/$UNINSTALL_OPERA_SCRIPT"
# Remove the last part of stable stream name
OPERA_STREAM=$(echo $OPERA_STREAM | sed 's/\-stable//')
# Record the version number in the package
cd "$OPERA_FILES"
touch usr/local/lib$LIBDIRSUFFIX/$OPERA_STREAM/VERSION_$OPERA_VERSION
# Finish uninstall script
printf 'set -e\nremovefiles << FILE_LIST\n' >> ".$UNINSTALL_OPERA_SCRIPT"
find . ! -type d ! -print | sed 's,\.,,' | grep -vF "$UNINSTALL_OPERA_SCRIPT" >> ".$UNINSTALL_OPERA_SCRIPT"
find . -depth -type d -print | sed 's,\.,,' | \
grep -vxE '(^$|/usr(/local(/bin|/lib(64)?|/share(/doc|/man(/man1)?)?)?)?)' >> ".$UNINSTALL_OPERA_SCRIPT"
printf "FILE_LIST\nupdatedbs\nrm -v \"$UNINSTALL_OPERA_SCRIPT\"\n" >> ".$UNINSTALL_OPERA_SCRIPT"
chmod 755 ".$UNINSTALL_OPERA_SCRIPT"
# Install the files only, *not* directories.
# This avoids changing system directory permissions/ownership
printf "Installing Opera ...\n\n"
find . ! -type d | tar -cf- -T- | tar -xf- -C /
# Note: Originally I used a cpio instead of a tar pipe but some
# systems might not have cpio installed by default.
# find . ! -type d | cpio --quiet -pmd /
# Remove temporary files
cd - >/dev/null
rm -r "$OPERA_FILES"
if [ "$DESTROY_DEB" = "Y" ]; then
rm "$OPERA_DEB"
fi
# Correct the Opera sandbox permissions (not needed if you want to run Opera 29+ and have a Linux kernel of 3.17 or newer)
chmod 4755 /usr/local/lib$LIBDIRSUFFIX/$OPERA_STREAM/opera_sandbox
# Update the desktop and icons databases
updatedbs
# And ... we're done! ;)
echo 'Opera was successfully installed into "/usr/local/"'.
printf "\nTo uninstall, issue the following as root (or prefaced with sudo):\n\n"
printf " $UNINSTALL_OPERA_SCRIPT\n\n"
exit
@ruario
Copy link
Author

ruario commented Apr 25, 2014

Read Manual Opera Install Instructions, for a summary of how this script works.

@the-nic
Copy link

the-nic commented Nov 10, 2014

It would be nice to be able to change the prefix from /usr/local to some other (e.g. in home: ~/.opt/opera-dev)

@ruario
Copy link
Author

ruario commented Nov 13, 2014

@the-nic I presume you want to install to a location such as this to avoid needing root privileges. However, you will still need root privileges as the opera_sandbox needs to be setuid as root to be able to setup a chroot like environment to separate Opera's renderer from the rest of the system. This is one of the security features of Chromium-based browsers. In addition many people's home folders are mounted on partitions with nosuid set, thus even with root permission Opera could not be run from such a location.

In short while I could tweak my script to install to other locations, this would just increase the likelihood of a broken install.

Why did you want this or what were you hoping to achieve? Perhaps I can think of another option for you?

@ruario
Copy link
Author

ruario commented Nov 13, 2014

If you wanted to place everything in ~/.opt/opera-dev so that you would have an easy uninstall (i.e. delete ~/.opt/opera-dev), keep in mind that an uninstall script is created anyway, so uninstall is as simple as:

sudo /usr/local/bin/remove-opera-developer

@stogdan
Copy link

stogdan commented Dec 12, 2014

It works mostly great for Fedora 21. However it does not seem to include icons? When I installed opera-beta with your script it lacks an icon both in gnome 3 application menu and in dash if I add it as a favorite. Perhaps I am doing something wrong, any suggestions?

Do not know if it is relevant for this issue. But I also see that the opera-beta.desktop does not exist under /usr/share/applications/ after install.

@ruario
Copy link
Author

ruario commented Dec 14, 2014

@stogdan My script installs Opera into /usr/local not the top level of /usr. I suspect this is the very first desktop orientated program you have installed into /usr/local, therefore your Gnome 3 is not yet scanning /usr/local/share/icons/hicolor/. You can rectify this by logging out of Gnome 3 and then back in again. After this point the icon will be found, just like any other application.

You can also confirm for yourself that the desktop and icon files are present via the following command:

$ ls /usr/local/share/applications /usr/local/share/icons/hicolor/128x128/apps

P.S. I install into /usr/local as this is the correct place for software that is outside of the default package manager (in your case rpm).

@ruario
Copy link
Author

ruario commented Dec 14, 2014

I have now added a comment to the README.md so others are not confused by this. So thanks for pointing this out and reminding me.

@ruario
Copy link
Author

ruario commented Jan 11, 2015

I have tweaked the install script to do a network install of Opera stable if no options are provided and no deb defined, stopped installation if the same version is already present, changed it so that compatibility symlinks are only created if needed and set sandbox permissions in post install (which should be more robust).

@Pepan
Copy link

Pepan commented Apr 1, 2015

Hi, I ma trying to use it on Fedora 21 fresh installation but it ends on
Uncompressing Opera ...
Touch ... „usr/local/lib64/opera/VERSION_28.0.1750.48“ ...does not exists... and it really does not. All files remains in tmp

Any help?

@ftonello
Copy link

ftonello commented Apr 2, 2015

Yes, I have a patch to fix it.

diff --git a/install-opera.sh b/install-opera.sh
index 6294a32..5c19c19 100644
--- a/install-opera.sh
+++ b/install-opera.sh
@@ -188,6 +188,8 @@ sed -n '1,/^} #$/p' "$0" > "$OPERA_FILES/$UNINSTALL_OPERA_SCRIPT"
 # Remove the last part of stable stream name
 OPERA_STREAM=$(echo $OPERA_STREAM | sed 's/\-stable//')

+cd $OPERA_FILES
+
 # Record the version number in the package
 touch usr/local/lib$LIBDIRSUFFIX/$OPERA_STREAM/VERSION_$OPERA_VERSION

Just the icons I cannot see it on KDE Launcher. Any ideas?

@ruario
Copy link
Author

ruario commented Apr 7, 2015

@ftonello: yep, looks like I broke the script after my last update to remove the udev and libcrypto workarounds. Thanks for helping @Pepan out. I have updated the script now.

Just the icons I cannot see it on KDE Launcher. Any ideas?

Did you follow the steps in the README.md

After install, you may need to re-login to your desktop environment before Opera is detected.

The problem is that KDE will not look for icons under /usr/local/share/icons/hicolor/ if none are there when it first starts up. A relog will fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment