Last active
April 2, 2025 10:09
-
-
Save Tiryoh/2fac7de1a90e23fa21dcdac898dd2694 to your computer and use it in GitHub Desktop.
Cursor Installation Script for Ubuntu (supports 0.46 or later)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -euo pipefail | |
# script version: 2025-04-02-1 | |
# reference: https://zenn.dev/ka2kama/articles/f0a6b5c2f32c87 | |
# Step 0: Check dependencies | |
if [ -z "$(which curl)" ]; then | |
echo curl command not found! | |
exit 1 | |
fi | |
if [ -z "$(which update-desktop-database)" ]; then | |
echo update-desktop-database command not found! | |
exit 1 | |
fi | |
# Step 1: Declare installation paths and variables | |
CURSOR_DIR="$HOME/Applications/cursor" | |
APPIMAGE_DIR="$CURSOR_DIR/images" | |
EXTRACTED_DIR="$CURSOR_DIR/squashfs-root" | |
BIN_PATH="$EXTRACTED_DIR/usr/bin/cursor" | |
DESKTOP_DIR="$HOME/.local/share/applications" | |
DESKTOP_FILE_PATH="$DESKTOP_DIR/cursor.desktop" | |
SCRIPT_PATH="$HOME/.local/bin/cursor" | |
ICON_PATH="$HOME/.local/share/icons/cursor.png" | |
LOG_FILE_PATH="$HOME/.local/share/cursor/cursor.log" | |
# DOWNLOAD_URL="https://downloader.cursor.sh/linux/appImage/x64" # only availabe for version before 0.46.0 | |
DOWNLOAD_URL="" | |
DOWNLOAD_LIST_URL="https://raw.githubusercontent.com/oslook/cursor-ai-downloads/refs/heads/main/README.md" | |
APPIMAGE_PREFIX_REV1="cursor-" # only availabe for version before 0.46.0 | |
APPIMAGE_SUFFIX_REV1="x86_64.AppImage" # only availabe for version before 0.46.0 | |
APPIMAGE_PREFIX_REV2="Cursor-" # only availabe for version 0.46 and 0.47 | |
APPIMAGE_SUFFIX_REV2="-[0-9a-fA-F]{40}\.deb\.glibc.*-x86_64\.AppImage" # only availabe for version 0.46 and 0.47 | |
APPIMAGE_PREFIX="Cursor-" | |
APPIMAGE_SUFFIX="-x86_64\.AppImage" | |
MAX_KEEP_INSTALLED_VERSIONS=3 | |
# Step 2: Create required directories | |
mkdir -p "$APPIMAGE_DIR" \ | |
"$DESKTOP_DIR" \ | |
"$(dirname "$SCRIPT_PATH")" \ | |
"$(dirname "$ICON_PATH")" \ | |
"$(dirname "$LOG_FILE_PATH")" | |
cd "$CURSOR_DIR" | |
# Step 3: Download latest version if not already installed | |
# 3.1: Check current installation | |
CURRENT_APPIMAGE_PATH=$(find "$APPIMAGE_DIR" -name "$APPIMAGE_PREFIX*AppImage" -printf '%f\n' \ | |
| sort -Vr \ | |
| head -n 1) | |
if [ -z "${CURRENT_APPIMAGE_PATH}" ]; then | |
CURRENT_APPIMAGE_PATH=$(find "$APPIMAGE_DIR" -name "$APPIMAGE_PREFIX_REV1*AppImage" -printf '%f\n' \ | |
| sort -Vr \ | |
| head -n 1) | |
fi | |
CURRENT_VERSION=$(basename "$CURRENT_APPIMAGE_PATH" | sed -E "s/^$APPIMAGE_PREFIX//; s/$APPIMAGE_SUFFIX$//") | |
# 3.2: Fetch latest version information | |
#LATEST_APPIMAGE=$(curl --range 0-0 -si "$DOWNLOAD_URL" \ | |
# | grep -i 'Content-Disposition' \ | |
# | awk -F'filename=' '{print $2}' \ | |
# | tr -d '\r\n"') # only availabe for version before 0.46.0 | |
if [ -z "$DOWNLOAD_URL" ]; then | |
DOWNLOAD_URL="$(curl -s "$DOWNLOAD_LIST_URL" | grep -oE "https://downloads\.cursor\.com/production/[0-9a-fA-F]*/linux/x64(/appimage)?/${APPIMAGE_PREFIX}.*${APPIMAGE_SUFFIX}" | head -n 1)" | |
fi | |
LATEST_APPIMAGE=$(echo "$DOWNLOAD_URL" | sed -E "s#.*/(Cursor-[^/]+\.AppImage)#\1#") | |
LATEST_VERSION=$(echo "$LATEST_APPIMAGE" | sed -E "s/^$APPIMAGE_PREFIX//; s/$APPIMAGE_SUFFIX$//") | |
echo "Current: $CURRENT_VERSION" | |
echo "Latest : $LATEST_VERSION" | |
# 3.3: Download new version if not installed | |
if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then | |
echo "Downloading $LATEST_APPIMAGE..." | |
trap "rm -f ""$APPIMAGE_DIR"/"$LATEST_APPIMAGE""; echo -e '\nDownload cancelled. Cleaning up...'; exit 1" SIGINT | |
# curl -LOJ --remove-on-error "$DOWNLOAD_URL" --output-dir "$APPIMAGE_DIR" # this is availabe for Ubuntu 24.04 or later | |
# curl -LOJ "$DOWNLOAD_URL" --output-dir "$APPIMAGE_DIR" # this is availabe for Ubuntu 22.04 or later | |
pushd "$APPIMAGE_DIR" && curl -LOJ "$DOWNLOAD_URL" && popd | |
chmod +x "$APPIMAGE_DIR/$LATEST_APPIMAGE" | |
# Remove old AppImages, keeping only a constant number of versions | |
find "$APPIMAGE_DIR" -name "$APPIMAGE_PREFIX*$APPIMAGE_SUFFIX" \ | |
| sort -Vr \ | |
| tail -n +$((MAX_KEEP_INSTALLED_VERSIONS + 1)) \ | |
| xargs rm -f | |
else | |
echo "Already downloaded the latest version ($LATEST_VERSION)" | |
fi | |
# Step 4: Extract application binary | |
rm -rf "$EXTRACTED_DIR" | |
"$APPIMAGE_DIR/$LATEST_APPIMAGE" --appimage-extract | |
chmod +x "$BIN_PATH" | |
# Step 5: Configure application launcher | |
cat <<EOF > "$SCRIPT_PATH" | |
#!/bin/bash | |
# Show version number when --version or -v flag is used | |
if [ "\$1" = "--version" ] || [ "\$1" = "-v" ]; then | |
echo "Cursor version: $LATEST_VERSION" | |
exit 0 | |
fi | |
"$BIN_PATH" --no-sandbox "\$@" 2>&1 \ | |
| grep -v '@todesktop/runtime: skipping autoUpdater initialization because application is not in AppImage.' \ | |
>> "$LOG_FILE_PATH" | |
EOF | |
chmod +x "$SCRIPT_PATH" | |
# Step 6: Install application icon | |
cp "$EXTRACTED_DIR/code.png" "$ICON_PATH" | |
# Step 7: Create desktop integration | |
if [ ! -f "$DESKTOP_FILE_PATH" ] \ | |
|| [ "$(grep -oP '(?<=^Exec=).*' "$DESKTOP_FILE_PATH")" != "$SCRIPT_PATH" ] \ | |
|| [ "$(grep -oP '(?<=^Icon=).*' "$DESKTOP_FILE_PATH")" != "$ICON_PATH" ]; then | |
cat <<EOF > "$DESKTOP_FILE_PATH" | |
[Desktop Entry] | |
Name=Cursor | |
Exec=$SCRIPT_PATH | |
Terminal=false | |
Type=Application | |
Icon=$ICON_PATH | |
StartupWMClass=Cursor | |
Comment=AI-powered code editor | |
MimeType=x-scheme-handler/cursor; | |
Categories=Utility;Development | |
EOF | |
chmod +x "$DESKTOP_FILE_PATH" | |
echo "Desktop shortcut created successfully" | |
fi | |
# Step 8: Update system's desktop database | |
update-desktop-database "$DESKTOP_DIR" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment