Skip to content

Instantly share code, notes, and snippets.

@ruario
Last active November 11, 2024 21:31
Show Gist options
  • Save ruario/d5df7c7af918f86c64487d6c51dfff6f to your computer and use it in GitHub Desktop.
Save ruario/d5df7c7af918f86c64487d6c51dfff6f to your computer and use it in GitHub Desktop.
Steps to fetch and run Signal on a Linux desktop that is not deb or apt based

The following is a quick guide on how to manually download, extract and run Signal for Linux on a non-(deb)apt based distro (and includes a shell script that automates the entire process). This is for use when no suitable, native (re)package is available. It also includes some additional instructions on how to integrate with your desktop environment. Almost any recent distro (configured for desktop use) will likely have all the dependencies already installed—especially so if you already have any other Electron apps or a Chromium based browser installed, since they will require the same things.

[Note: Triple-click to easily select any of the lines below for copy and pasting into the terminal]

Fetch, extract and launch

  • Switch to a directory you think is suitable for housing Signal (for example ~/opt)
mkdir -p ~/opt && cd ~/opt
  • Download the latest .deb package
wget https://updates.signal.org/desktop/apt/`wget -qO- https://updates.signal.org/desktop/apt/dists/xenial/main/binary-amd64/Packages.gz | zgrep -m1 '^Filename:.*/signal-desktop/' | cut -d' ' -f2`

[Note: Version '7.32.0' as of the 11th of Nov 2024 at 21:30 UTC]

  • Extract the files
ar p "`ls -t signal-desktop_*.deb* | head -1`" data.tar.xz | tar xJ --one-top-level=signal-desktop

[Note: The ar command is found in the GNU Binutils package if you do not have it installed and the tar command assumes a fairly recent GNU tar]

  • Launch Signal
signal-desktop/opt/Signal/signal-desktop &

[Note: Repeat this last command every time you need to re-launch. You will need to either switch to the same working directory you used in the initial step first or simply adjust the path accordingly.]

Upgrades

If you want to check for a new version in the future, simply issue the following

wget -qO- https://updates.signal.org/desktop/apt/dists/xenial/main/binary-amd64/Packages.gz | zgrep -Exm1 'Version: ([0-9\.]+){2}[0-9\.]+'

If there is a new one and you do want to upgrade to it, just delete the "signal-desktop" directory then repeat the "Fetch, extract and launch" steps above.

[Note: You do not have to worry about accidentally deleting your settings when deleting the contents of the "install" directory ("signal-desktop"), as they are stored separately in "${XDG_CONFIG_HOME:-$HOME/.config}/Signal"]

Integrate with desktop environment

If you want to get a little advanced, you can even integrate the manually extracted copy of Signal with your Desktop Environment, so that it shows up in the desktop launcher, like any other installed application. 😉

[Note:You will need to issue these commands from the same working directory as the previous steps. Normally you should not need to repeat this for every upgrade. Unless there are new icons or major changes to the desktop file, doing it once is often enough. However repeating these steps is unlikely to be problematic]

  • Ensure that the XDG_DATA_HOME directory structure exists
mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/applications"
  • Copy icons into XDG_DATA_HOME
(cd signal-desktop/usr/share; find icons -name signal-desktop.png | cpio --quiet -pud "${XDG_DATA_HOME:-$HOME/.local/share}")
  • Copy a (tweaked) desktop file into XDG_DATA_HOME
sed "s,^Exec=.*signal-desktop[\(\" \) ],Exec=\"$PWD/signal-desktop/opt/Signal/signal-desktop\" ," signal-desktop/usr/share/applications/signal-desktop.desktop > "${XDG_DATA_HOME:-$HOME/.local/share}/applications/signal-desktop.desktop"
  • Register with your desktop environment
update-desktop-database -q "${XDG_DATA_HOME:-$HOME/.local/share}/applications"

[Note: You may need to re-login to your desktop environment before Signal shows up]


Should you wish to remove the desktop integration in the future issue the following

find "${XDG_DATA_HOME:-$HOME/.local/share}" -name signal-desktop.\* -delete

[Note: If it does not disappear immediately, either log out and back into your desktop environment or just issue that "update-desktop-database" command listed above again]

Automatic install, upgrade and uninstall (shell script)

For the lazy I also include a shell script that automates all of the above, including fetching upgrades and clean removal. It also handles the beta, alpha and staging streams. I tested it fairly well but review it and use at your own risk. 😉

For example to install the normal/stable verison, make the install script executable (chmod 755 fetch_signal_linux.sh) and then issue the following

./fetch_signal_linux.sh

To install the Beta stream instead

./fetch_signal_linux.sh --beta

[Note: Other switches include --alpha and --staging for those streams respectively]

#!/bin/sh -eu
helptext() {
cat << HELP
Usage:
$ ${0##*/} [<channel options>] [--unpack-dir <directory>] [--remove]
If no options are provided, this script will fetch and unpack the most recent
Signal for Linux (from the stable release channel) and associate it with your
desktop environment.
If you have run the script before to fetch a package, it will upgrade any
outdated copy of Signal (if a newer one is available when the script is
run again).
If you would like to fetch from one of the other channels (Beta, Alpha or
Staging) use one of the channel options listed below.
Clean removal of previous versions (fetched by this script) can be performed
by providing "--remove" in conjunction with the appropriate switch to specify
a channel. If no channel switch is provided then the stable release channel is
always assumed.
Channel options:
-b, --beta Beta releases
-a, --alpha Alpha releases
-s, --staging Staging releases
Additional options:
--unpack-dir <directory> Define an alternate directory to unpack
Signal into
--remove Remove a previously unpacked build and
dissociate it from your desktop environment
[ You need to provide a channel option in
addition to "--remove", should you wish to
remove a channel other than stable ]
-h, --help Show this help text (and exit)
HELP
}
# Set default values that can be changed with switches
SIGNAL_STREAM=signal-desktop
SIGNAL_APT_DIR=apt
SIGNAL_PRETTY_NAME=Signal
SIGNAL_INSTALL_DIR="${XDG_DATA_HOME:-$HOME/.local/share}"
SIGNAL_UNINSTALL=N
# Accept switches provided on the command line
while [ -n "${1:-}" ]; do
if [ "${1:-}" = "-b" -o "${1:-}" = "--beta" ]; then
SIGNAL_STREAM=signal-desktop-beta
SIGNAL_PRETTY_NAME="Signal Beta"
shift 1
elif [ "${1:-}" = "-a" -o "${1:-}" = "--alpha" ]; then
SIGNAL_STREAM=signal-desktop-alpha
SIGNAL_APT_DIR=apt-alpha
SIGNAL_PRETTY_NAME="Signal Alpha"
shift 1
elif [ "${1:-}" = "-s" -o "${1:-}" = "--staging" ]; then
SIGNAL_STREAM=signal-desktop-staging
SIGNAL_APT_DIR=apt-alpha
SIGNAL_PRETTY_NAME="Signal Staging"
shift 1
# Check if the switch provided starts with "--unpack-dir"
elif [ "$(echo "${1:-}" | cut -c1-12)" = "--unpack-dir" ]; then
# Check if a directory name is provided at the same time, e.g. "--unpack-dir=dirname"
if [ "$(echo "${1:-}" | cut -d= -f2-)" != "--unpack-dir" ]; then
# Include rudimentary handling for the most common use case of tilde expansion
SIGNAL_INSTALL_DIR="$(echo "${1:-}" | cut -d= -f2- | sed "s#^~#$HOME#")"
shift 1
# Check for a follow on switch to specify the directory name
elif [ -n "${2:-}" -a "$(echo "${2:-}" | cut -c1)" != "-" ]; then
SIGNAL_INSTALL_DIR="$2"
shift 2
else
echo "A directory name must be provided with the \"--unpack-dir\" switch" >&2
exit 1
fi
elif [ "${1:-}" = "--remove" ]; then
SIGNAL_UNINSTALL=Y
shift 1
elif [ "${1:-}" = "-h" -o "${1:-}" = "--help" ]; then
helptext
exit
else
echo "The switch \"${1:-}\" was not recognised; exiting" >&2
exit 1
fi
done
# Remove if the user requested this
if [ "$SIGNAL_UNINSTALL" = Y ]; then
SIGNAL_REMOVAL=''
for POSSIBLE_SIGNAL_REMOVAL in "$HOME/bin/remove-$SIGNAL_STREAM.sh" "$HOME/.local/bin/remove-$SIGNAL_STREAM.sh" "$SIGNAL_INSTALL_DIR/remove-$SIGNAL_STREAM.sh"; do
if [ -x "$POSSIBLE_SIGNAL_REMOVAL" ]; then
SIGNAL_REMOVAL="$POSSIBLE_SIGNAL_REMOVAL"
break
fi
done
if [ -n "$SIGNAL_REMOVAL" ]; then
echo "Running: $SIGNAL_REMOVAL ..."
"$SIGNAL_REMOVAL" && echo "Success!" || echo "Removal failed" >&2 && exit 1
exit
else
echo "Could not find an uninstall script for $SIGNAL_PRETTY_NAME" >&2
exit 1
fi
fi
# Check for a downloader: Wget or cURL
available () {
command -v "$1" >/dev/null 2>&1
}
if available wget; then
DL_SILENT="wget -qO-"
DL_LOUD=wget
DL_OUTPUT=-O
elif available curl; then
DL_SILENT="curl -fs"
DL_LOUD="curl -f"
DL_OUTPUT=-o
else
echo "You need to install Wget or cURL to retrieve the latest version of $SIGNAL_PRETTY_NAME" >&2
exit 1
fi
# Switch to the install directory
mkdir -p "$SIGNAL_INSTALL_DIR"
cd "$SIGNAL_INSTALL_DIR"
SIGNAL_INSTALL_DIR="$PWD"
# Check for a new Signal version or exit if there is nothing new
SIGNAL_VERSION="$($DL_SILENT https://updates.signal.org/desktop/$SIGNAL_APT_DIR/dists/xenial/main/binary-amd64/Packages.gz | gzip -d | grep -m1 "^Filename:.*/${SIGNAL_STREAM}_" | cut -d_ -f2)"
if [ -e "$SIGNAL_STREAM/$SIGNAL_VERSION" ]; then
echo "You already have the latest $SIGNAL_PRETTY_NAME ($SIGNAL_VERSION): $SIGNAL_INSTALL_DIR/$SIGNAL_STREAM" 1>&2
exit
fi
# Fetch the current (latest) deb package
SIGNAL_PKG="$(mktemp -t ${SIGNAL_STREAM}_${SIGNAL_VERSION}_tmp.XXXXXX)"
$DL_LOUD "https://updates.signal.org/desktop/$SIGNAL_APT_DIR/pool/s/$SIGNAL_STREAM/${SIGNAL_STREAM}_${SIGNAL_VERSION}_amd64.deb" $DL_OUTPUT "$SIGNAL_PKG"
# Remove any previous install before upgrading
for POSSIBLE_SIGNAL_REMOVAL in "$HOME/bin/remove-$SIGNAL_STREAM.sh" "$HOME/.local/bin/remove-$SIGNAL_STREAM.sh" "$SIGNAL_INSTALL_DIR/remove-$SIGNAL_STREAM.sh"; do
if [ -x "$POSSIBLE_SIGNAL_REMOVAL" ]; then
"$POSSIBLE_SIGNAL_REMOVAL"
break
fi
done
# Extract the most recently downloaded Signal deb package
data_extract () {
if available ar; then
ar p "$SIGNAL_PKG" data.tar.xz
else
# Fallback for `ar` (GNU binutils) not being present.
# Matching on up to the second occurance of the magic number (FD [37 7A 58 5A] 00), in case control.tar is XZ compressed in the future
tail -c+"$(grep -Fabom2 7zXZ "$SIGNAL_PKG" | tail -n1 | cut -d: -f1)" "$SIGNAL_PKG"
fi
}
mkdir -p "$SIGNAL_STREAM"
data_extract | tar -xJf- -C "$SIGNAL_STREAM"
touch "$SIGNAL_STREAM/$SIGNAL_VERSION"
# Remove the .deb package as it is no longer needed
rm "$SIGNAL_PKG"
# Symlink icons into XDG_DATA_HOME
cd "$SIGNAL_STREAM/usr/share"
for SIGNAL_ICON in "icons/hicolor/"*"/apps/$SIGNAL_STREAM.png"; do
mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/${SIGNAL_ICON%/*}"
ln -fs "$SIGNAL_INSTALL_DIR/$SIGNAL_STREAM/usr/share/$SIGNAL_ICON" "${XDG_DATA_HOME:-$HOME/.local/share}/$SIGNAL_ICON"
done
cd "$SIGNAL_INSTALL_DIR"
# Install desktop file patched with new "install" path
mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/applications"
SIGNAL_BIN="$SIGNAL_INSTALL_DIR/$SIGNAL_STREAM/opt/$SIGNAL_PRETTY_NAME/$SIGNAL_STREAM"
sed "s,Exec=.*$SIGNAL_STREAM[\(\" \) ],Exec=\"$SIGNAL_BIN\" ," "$SIGNAL_STREAM/usr/share/applications/$SIGNAL_STREAM.desktop" > "${XDG_DATA_HOME:-$HOME/.local/share}/applications/$SIGNAL_STREAM.desktop"
# Let the desktop environment know there is a newly installed Signal
update-desktop-database -q "${XDG_DATA_HOME:-$HOME/.local/share}/applications" 2>/dev/null ||:
# Check for a user bin directory as this is likely in the $PATH
if [ -d "$HOME/bin" -a -w "$HOME/bin" ]; then
ln -fs "$SIGNAL_BIN" "$HOME/bin/$SIGNAL_STREAM"
SIGNAL_BIN="$HOME/bin/$SIGNAL_STREAM"
SIGNAL_REMOVAL="$HOME/bin/remove-$SIGNAL_STREAM.sh"
elif [ -d "$HOME/.local/bin" -a -w "$HOME/.local/bin" ]; then
ln -fs "$SIGNAL_BIN" "$HOME/.local/bin/$SIGNAL_STREAM"
SIGNAL_BIN="$HOME/.local/bin/$SIGNAL_STREAM"
SIGNAL_REMOVAL="$HOME/.local/bin/remove-$SIGNAL_STREAM.sh"
else
SIGNAL_REMOVAL="$SIGNAL_INSTALL_DIR/remove-$SIGNAL_STREAM.sh"
fi
# Create removal script
cat << SCRIPT > "$SIGNAL_REMOVAL"
#!/bin/sh
SIGNAL_REMOVE_FAIL=0
chkdel () {
"\$@" || SIGNAL_REMOVE_FAIL=1
}
[ -h "$SIGNAL_BIN" ] && chkdel rm "$SIGNAL_BIN"
chkdel rm "${XDG_DATA_HOME:-$HOME/.local/share}/applications/$SIGNAL_STREAM.desktop"
chkdel find "${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor" -name "$SIGNAL_STREAM.png" -type l -delete
chkdel rm -r "$SIGNAL_INSTALL_DIR/$SIGNAL_STREAM"
if [ "\$SIGNAL_REMOVE_FAIL" = 0 ]; then
rm "$SIGNAL_REMOVAL"
else
echo "Some files could not be removed! Retaining: \"$SIGNAL_REMOVAL\"" >&2
exit 1
fi
SCRIPT
chmod 755 "$SIGNAL_REMOVAL"
# Tips on launching Signal and how to remove it
cat << TIPS
$SIGNAL_PRETTY_NAME ($SIGNAL_VERSION) will now show up within the menus of your desktop environment.
Alternatively, you can also start it from the terminal like so:
"$SIGNAL_BIN" &
** The following command will allow you to remove $SIGNAL_PRETTY_NAME in the future, should you want to. **
"$SIGNAL_REMOVAL"
TIPS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment