2020-10-16 16:18:57 +02:00
#!/usr/bin/env bash
2018-10-03 20:48:14 +02:00
set -e
2019-02-16 15:13:33 +02:00
2021-08-10 20:52:32 +02:00
trap 'handleError' ERR
handleError( ) {
2024-01-23 18:42:03 +02:00
echo ""
echo "If you encountered an error, please consider fixing"
echo "the script for your environment and creating a pull"
echo "request instead of asking for support on GitHub or"
echo "the forum. The error message above should tell you"
echo "where and why the error happened."
2021-08-10 20:52:32 +02:00
}
2019-02-16 15:13:33 +02:00
#-----------------------------------------------------
# Variables
#-----------------------------------------------------
2024-01-23 18:14:14 +02:00
# Only set colors, if tput available and TERM is recognized
if [ [ ` command -v tput` && ` tput setaf 1 2>/dev/null` ] ] ; then
COLOR_RED = ` tput setaf 1`
COLOR_GREEN = ` tput setaf 2`
COLOR_YELLOW = ` tput setaf 3`
COLOR_BLUE = ` tput setaf 4`
COLOR_RESET = ` tput sgr0`
fi
2019-10-05 19:14:45 +02:00
SILENT = false
2020-03-28 03:58:04 +02:00
ALLOW_ROOT = false
SHOW_CHANGELOG = false
2020-06-07 11:00:06 +02:00
INCLUDE_PRE_RELEASE = false
2024-07-31 14:57:04 +02:00
INSTALL_DIR = " ${ HOME } /.joplin " # default installation directory
2019-10-05 19:14:45 +02:00
print( ) {
2024-01-23 18:42:03 +02:00
if [ [ " ${ SILENT } " = = false ] ] ; then
echo -e " $@ "
fi
2019-10-05 19:14:45 +02:00
}
2020-03-28 03:58:04 +02:00
showLogo( ) {
2024-01-23 18:42:03 +02:00
print " ${ COLOR_BLUE } "
print " _ _ _ "
print " | | ___ _ __ | (_)_ __ "
print " _ | |/ _ \| '_ \| | | '_ \ "
print "| |_| | (_) | |_) | | | | | |"
print " \___/ \___/| .__/|_|_|_| |_|"
print " |_|"
print ""
print "Linux Installer and Updater"
print " ${ COLOR_RESET } "
2020-03-28 03:58:04 +02:00
}
showHelp( ) {
2024-01-23 18:42:03 +02:00
showLogo
print "Available Arguments:"
print "\t" "--help" "\t" "Show this help information" "\n"
print "\t" "--allow-root" "\t" "Allow the install to be run as root"
print "\t" "--changelog" "\t" "Show the changelog after installation"
print "\t" "--force" "\t" "Always download the latest version"
print "\t" "--silent" "\t" "Don't print any output"
print "\t" "--prerelease" "\t" "Check for new Versions including Pre-Releases"
2024-07-31 14:57:04 +02:00
print "\t" "--install-dir" "\t" " Set installation directory; default: \" ${ INSTALL_DIR } \" "
2024-01-23 18:42:03 +02:00
if [ [ ! -z $1 ] ] ; then
print "\n" " ${ COLOR_RED } ERROR: " " $* " " ${ COLOR_RESET } " "\n"
else
exit 0
fi
2020-03-28 03:58:04 +02:00
}
2019-10-05 19:14:45 +02:00
#-----------------------------------------------------
2020-03-28 03:58:04 +02:00
# PARSE ARGUMENTS
2019-10-05 19:14:45 +02:00
#-----------------------------------------------------
2018-10-24 20:17:18 +02:00
2020-03-28 03:58:04 +02:00
optspec = ":h-:"
while getopts " ${ optspec } " OPT; do
[ " ${ OPT } " = " " ] && continue
if [ " ${ OPT } " = "-" ] ; then # long option: reformulate OPT and OPTARG
2024-01-23 18:42:03 +02:00
OPT = " ${ OPTARG %%=* } " # extract long option name
OPTARG = " ${ OPTARG # $OPT } " # extract long option argument (may be empty)
OPTARG = " ${ OPTARG #= } " # if long option argument, remove assigning `=`
2018-11-20 23:54:58 +02:00
fi
2020-03-28 03:58:04 +02:00
case " ${ OPT } " in
h | help ) showHelp ; ;
allow-root ) ALLOW_ROOT = true ; ;
silent ) SILENT = true ; ;
force ) FORCE = true ; ;
changelog ) SHOW_CHANGELOG = true ; ;
2020-06-07 11:00:06 +02:00
prerelease ) INCLUDE_PRE_RELEASE = true ; ;
2024-07-31 14:57:04 +02:00
install-dir ) INSTALL_DIR = " $OPTARG " ; ;
2020-03-28 03:58:04 +02:00
[ ^\? ] * ) showHelp " Illegal option -- ${ OPT } " ; exit 2 ; ;
\? ) showHelp " Illegal option - ${ OPTARG } " ; exit 2 ; ;
esac
done
shift $(( OPTIND-1)) # remove parsed options and args from $@ list
2018-11-20 23:54:58 +02:00
2020-03-28 03:58:04 +02:00
## Check and warn if running as root.
if [ [ $EUID = 0 ] ] && [ [ " ${ ALLOW_ROOT } " != true ] ] ; then
2024-01-23 18:42:03 +02:00
showHelp "It is not recommended (nor necessary) to run this script as root. To do so anyway, please use '--allow-root'"
exit 1
2019-10-05 19:14:45 +02:00
fi
#-----------------------------------------------------
# START
#-----------------------------------------------------
2020-03-28 03:58:04 +02:00
showLogo
2019-10-05 19:14:45 +02:00
2020-05-09 12:23:42 +02:00
#-----------------------------------------------------
2020-03-28 03:58:04 +02:00
print "Checking architecture..."
2020-05-09 12:23:42 +02:00
## uname actually gives more information than needed, but it contains all architectures (hardware and software)
2020-07-23 00:16:42 +02:00
ARCHITECTURE = $( uname -m -p -i || echo "NO CHECK" )
2020-03-24 19:08:07 +02:00
2024-01-23 18:42:03 +02:00
if [ [ $ARCHITECTURE = "NO CHECK" ] ] ; then
2020-05-09 12:23:42 +02:00
print " ${ COLOR_YELLOW } WARNING: Can't get system architecture, skipping check ${ COLOR_RESET } "
2024-01-23 18:42:03 +02:00
elif [ [ $ARCHITECTURE = ~ .*aarch.*| .*arm.* ] ] ; then
2020-05-09 12:23:42 +02:00
showHelp "Arm systems are not officially supported by Joplin, please search the forum (https://discourse.joplinapp.org/) for more information"
exit 1
2024-01-23 18:42:03 +02:00
elif [ [ $ARCHITECTURE = ~ .*i386.*| .*i686.* ] ] ; then
2020-05-09 12:23:42 +02:00
showHelp "32-bit systems are not supported by Joplin, please search the forum (https://discourse.joplinapp.org/) for more information"
exit 1
2020-03-24 19:08:07 +02:00
fi
2018-10-24 20:17:18 +02:00
#-----------------------------------------------------
2023-05-16 12:57:50 +02:00
print "Checking dependencies..."
## Check if libfuse2 is present.
2023-05-18 18:46:58 +02:00
if [ [ $( command -v ldconfig) ] ] ; then
2024-07-16 20:20:51 +02:00
LIBFUSE = $( ldconfig -p | grep "libfuse.so.2" || echo '' )
fi
if [ [ $LIBFUSE = = "" ] ] ; then
LIBFUSE = $( find /lib /usr/lib /lib64 /usr/lib64 /usr/local/lib -name "libfuse.so.2" 2>/dev/null | grep "libfuse.so.2" || echo '' )
2023-05-18 18:46:58 +02:00
fi
2024-01-23 18:42:03 +02:00
if [ [ $LIBFUSE = = "" ] ] ; then
2023-05-16 12:57:50 +02:00
print " ${ COLOR_RED } Error: Can't get libfuse2 on system, please install libfuse2 ${ COLOR_RESET } "
2023-11-07 14:01:00 +02:00
print "See https://joplinapp.org/help/faq/#desktop-application-will-not-launch-on-linux and https://github.com/AppImage/AppImageKit/wiki/FUSE for more information"
2023-05-16 12:57:50 +02:00
exit 1
fi
#-----------------------------------------------------
2020-03-30 19:36:10 +02:00
# Download Joplin
#-----------------------------------------------------
# Get the latest version to download
2020-06-07 11:00:06 +02:00
if [ [ " $INCLUDE_PRE_RELEASE " = = true ] ] ; then
2021-10-22 16:21:39 +02:00
RELEASE_VERSION = $( wget -qO - "https://api.github.com/repos/laurent22/joplin/releases" | grep -Po '"tag_name": ?"v\K.*?(?=")' | sort -rV | head -1)
2020-06-07 11:00:06 +02:00
else
RELEASE_VERSION = $( wget -qO - "https://api.github.com/repos/laurent22/joplin/releases/latest" | grep -Po '"tag_name": ?"v\K.*?(?=")' )
fi
2018-10-03 20:48:14 +02:00
2018-10-24 20:17:18 +02:00
# Check if it's in the latest version
2024-07-31 14:57:04 +02:00
if [ [ -e " ${ INSTALL_DIR } /VERSION " ] ] && [ [ $( < " ${ INSTALL_DIR } /VERSION " ) = = " ${ RELEASE_VERSION } " ] ] ; then
2024-01-23 18:42:03 +02:00
print " ${ COLOR_GREEN } You already have the latest version ${ COLOR_RESET } ${ RELEASE_VERSION } ${ COLOR_GREEN } installed. ${ COLOR_RESET } "
( [ [ " $FORCE " = = true ] ] && print "Forcing installation..." ) || exit 0
2020-03-28 03:58:04 +02:00
else
2024-07-31 14:57:04 +02:00
[ [ -e " ${ INSTALL_DIR } /VERSION " ] ] && CURRENT_VERSION = $( < " ${ INSTALL_DIR } /VERSION " )
2024-01-23 18:42:03 +02:00
print " The latest version is ${ RELEASE_VERSION } , but you have ${ CURRENT_VERSION :- no version } installed. "
2020-03-28 03:58:04 +02:00
fi
2023-05-11 19:44:02 +02:00
# Check if it's an update or a new install
DOWNLOAD_TYPE = "New"
2024-07-31 14:57:04 +02:00
if [ [ -f " ${ INSTALL_DIR } /Joplin.AppImage " ] ] ; then
2024-01-23 18:42:03 +02:00
DOWNLOAD_TYPE = "Update"
2023-05-11 19:44:02 +02:00
fi
2020-03-28 03:58:04 +02:00
#-----------------------------------------------------
print 'Downloading Joplin...'
TEMP_DIR = $( mktemp -d)
2023-05-11 19:44:02 +02:00
wget -O " ${ TEMP_DIR } /Joplin.AppImage " " https://objects.joplinusercontent.com/v ${ RELEASE_VERSION } /Joplin- ${ RELEASE_VERSION } .AppImage?source=LinuxInstallScript&type= $DOWNLOAD_TYPE "
2021-09-19 03:59:26 +02:00
wget -O " ${ TEMP_DIR } /joplin.png " https://joplinapp.org/images/Icon512.png
2018-10-03 20:48:14 +02:00
2020-03-28 03:58:04 +02:00
#-----------------------------------------------------
print 'Installing Joplin...'
# Delete previous version (in future versions joplin.desktop shouldn't exist)
2024-07-31 14:57:04 +02:00
rm -f " ${ INSTALL_DIR } " /*.AppImage ~/.local/share/applications/joplin.desktop " ${ INSTALL_DIR } /VERSION "
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
# Creates the folder where the binary will be stored
2024-07-31 14:57:04 +02:00
mkdir -p " ${ INSTALL_DIR } / "
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
# Download the latest version
2024-07-31 14:57:04 +02:00
mv " ${ TEMP_DIR } /Joplin.AppImage " " ${ INSTALL_DIR } /Joplin.AppImage "
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
# Gives execution privileges
2024-07-31 14:57:04 +02:00
chmod +x " ${ INSTALL_DIR } /Joplin.AppImage "
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
print " ${ COLOR_GREEN } OK ${ COLOR_RESET } "
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
#-----------------------------------------------------
print 'Installing icon...'
mkdir -p ~/.local/share/icons/hicolor/512x512/apps
2021-09-19 03:59:26 +02:00
mv " ${ TEMP_DIR } /joplin.png " ~/.local/share/icons/hicolor/512x512/apps/joplin.png
2020-03-28 03:58:04 +02:00
print " ${ COLOR_GREEN } OK ${ COLOR_RESET } "
# Detect desktop environment
2024-01-23 18:42:03 +02:00
if [ " $XDG_CURRENT_DESKTOP " = "" ] ; then
2020-03-28 03:58:04 +02:00
DESKTOP = $( echo " ${ XDG_DATA_DIRS } " | sed 's/.*\(xfce\|kde\|gnome\).*/\1/' )
else
DESKTOP = $XDG_CURRENT_DESKTOP
fi
DESKTOP = ${ DESKTOP ,, } # convert to lower case
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
echo 'Create Desktop icon...'
2021-08-18 13:01:58 +02:00
# Detect distribution environment, and apply --no-sandbox fix
SANDBOXPARAM = ""
# lsb_release isn't available on some platforms (e.g. opensuse)
# The equivalent of lsb_release in OpenSuse is the file /usr/lib/os-release
if command -v lsb_release & > /dev/null; then
DISTVER = $( lsb_release -is) && DISTVER = $DISTVER $( lsb_release -rs)
DISTCODENAME = $( lsb_release -cs)
2021-09-05 21:53:24 +02:00
DISTMAJOR = $( lsb_release -rs| cut -d. -f1)
2024-04-20 14:52:26 +02:00
2021-08-18 13:01:58 +02:00
#-----------------------------------------------------
# Check for "The SUID sandbox helper binary was found, but is not configured correctly" problem.
# It is present in Debian 1X. A (temporary) patch will be applied at .desktop file
# Linux Mint 4 Debbie is based on Debian 10 and requires the same param handling.
2023-11-14 20:49:25 +02:00
#
2024-04-20 14:52:26 +02:00
# TODO: Remove: This is likely no longer an issue. See https://issues.chromium.org/issues/40462640.
BAD_HELPER_BINARY = false
if [ [ $DISTVER = ~ Debian1. || ( " $DISTVER " = "Linuxmint4" && " $DISTCODENAME " = "debbie" ) || ( " $DISTVER " = "CentOS" && " $DISTMAJOR " = ~ 6| 7 ) ] ] ; then
BAD_HELPER_BINARY = true
fi
# Work around Ubuntu 23.10+'s restrictions on unprivileged user namespaces. Electron
2023-11-14 20:49:25 +02:00
# uses these to sandbox processes. Unfortunately, it doesn't look like we can get around this
# without writing the AppImage to a non-user-writable location (without invalidating other security
# controls). See https://discourse.joplinapp.org/t/possible-future-requirement-for-no-sandbox-flag-for-ubuntu-23-10/.
2024-04-20 14:52:26 +02:00
HAS_USERNS_RESTRICTIONS = false
if [ [ " $DISTVER " = ~ ^Ubuntu && $DISTMAJOR -ge 23 ] ] ; then
HAS_USERNS_RESTRICTIONS = true
fi
if [ [ $HAS_USERNS_RESTRICTIONS = true || $BAD_HELPER_BINARY = true ] ] ; then
2021-10-16 11:07:41 +02:00
SANDBOXPARAM = "--no-sandbox"
2023-11-14 20:49:25 +02:00
print " ${ COLOR_YELLOW } WARNING ${ COLOR_RESET } Electron sandboxing disabled. "
print " See https://discourse.joplinapp.org/t/32160/5 for details."
2021-08-18 13:01:58 +02:00
fi
2021-03-11 16:47:18 +02:00
fi
2021-01-27 23:45:49 +02:00
# Initially only desktop environments that were confirmed to use desktop files stored in
# `.local/share/desktop` had a desktop file created.
# However some environments don't return a desktop BUT still support these desktop files
# the command check was added to support all Desktops that have support for the
2024-01-23 18:14:14 +02:00
# freedesktop standard
2021-01-27 23:45:49 +02:00
# The old checks are left in place for historical reasons, but
# NO MORE DESKTOP ENVIRONMENTS SHOULD BE ADDED
# If a new environment needs to be supported, then the command check section should be re-thought
2024-01-23 18:42:03 +02:00
if [ [ $DESKTOP = ~ .*gnome.*| .*kde.*| .*xfce.*| .*mate.*| .*lxqt.*| .*unity.*| .*x-cinnamon.*| .*deepin.*| .*pantheon.*| .*lxde.*| .*i3.*| .*sway.* ] ] || [ [ ` command -v update-desktop-database` ] ] ; then
DATA_HOME = ${ XDG_DATA_HOME :- ~/.local/share }
DESKTOP_FILE_LOCATION = " $DATA_HOME /applications "
# Only delete the desktop file if it will be replaced
rm -f " $DESKTOP_FILE_LOCATION /appimagekit-joplin.desktop "
# On some systems this directory doesn't exist by default
mkdir -p " $DESKTOP_FILE_LOCATION "
# No spaces or tabs should be used for indentation with Bash heredocs
cat >> " $DESKTOP_FILE_LOCATION /appimagekit-joplin.desktop " <<-EOF
[ Desktop Entry]
Encoding = UTF-8
Name = Joplin
Comment = Joplin for Desktop
2024-07-31 14:57:04 +02:00
Exec = env APPIMAGELAUNCHER_DISABLE = TRUE " ${ INSTALL_DIR } /Joplin.AppImage " ${ SANDBOXPARAM } %u
2024-01-23 18:42:03 +02:00
Icon = joplin
StartupWMClass = Joplin
Type = Application
Categories = Office;
MimeType = x-scheme-handler/joplin;
2024-11-05 11:06:10 +02:00
# should be removed eventually as it was upstream to be an XDG specification
X-GNOME-SingleWindow= true
2024-01-23 18:42:03 +02:00
SingleMainWindow = true
EOF
# Update application icons
[ [ ` command -v update-desktop-database` ] ] && update-desktop-database " $DESKTOP_FILE_LOCATION " && update-desktop-database " $DATA_HOME /icons "
print " ${ COLOR_GREEN } OK ${ COLOR_RESET } "
2020-03-28 03:58:04 +02:00
else
2024-01-23 18:42:03 +02:00
print " ${ COLOR_RED } NOT DONE, unknown desktop ' ${ DESKTOP } ' ${ COLOR_RESET } "
2020-03-28 03:58:04 +02:00
fi
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
#-----------------------------------------------------
# FINISH INSTALLATION
#-----------------------------------------------------
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
# Informs the user that it has been installed
print " ${ COLOR_GREEN } Joplin version ${ COLOR_RESET } ${ RELEASE_VERSION } ${ COLOR_GREEN } installed. ${ COLOR_RESET } "
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
# Record version
2024-07-31 14:57:04 +02:00
echo " $RELEASE_VERSION " > " ${ INSTALL_DIR } /VERSION "
2020-03-28 03:58:04 +02:00
#-----------------------------------------------------
if [ [ " $SHOW_CHANGELOG " = = true ] ] ; then
2024-01-23 18:42:03 +02:00
NOTES = $( wget -qO - https://api.github.com/repos/laurent22/joplin/releases/latest | grep -Po '"body": "\K.*(?=")' )
print " ${ COLOR_BLUE } Changelog: ${ COLOR_RESET } \n ${ NOTES } "
2018-10-03 20:48:14 +02:00
fi
2019-10-05 19:14:45 +02:00
2020-03-28 03:58:04 +02:00
#-----------------------------------------------------
print "Cleaning up..."
2021-09-19 03:59:26 +02:00
rm -rf " $TEMP_DIR "
2020-03-28 03:58:04 +02:00
print " ${ COLOR_GREEN } OK ${ COLOR_RESET } "