Skip to content

Instantly share code, notes, and snippets.

@jimkring
Created May 23, 2026 23:36
Show Gist options
  • Select an option

  • Save jimkring/24f841927fe6f33677376da34c13afc1 to your computer and use it in GitHub Desktop.

Select an option

Save jimkring/24f841927fe6f33677376da34c13afc1 to your computer and use it in GitHub Desktop.
script for installing/updating lmstudio on ubuntu

update_lmstudio.sh

Updates LM Studio to the latest Linux release and keeps its launcher icon working.

What it does

  • Checks the version before downloading. It reads the real package version from just the first 2 MiB of the .deb (an HTTP range request) and compares it to the installed dpkg version. The full ~650 MB download and sudo dpkg -i only happen when a newer version actually exists.
  • Fixes the missing app icon. LM Studio's .deb installs its icon into an invalid hicolor/0x0/ directory that the desktop ignores, so the app ships with no icon. After installing, the script copies the package's 1024×1024 icon into ~/.local/share/icons/hicolor/512x512/apps/ — per-user, so it survives future upgrades (the packaging bug is not fixed by upgrading).

Usage

./update_lmstudio.sh
#!/bin/bash
set -e
PKG="lm-studio"
URL="https://lmstudio.ai/download/latest/linux/x64?format=deb"
UA="Mozilla/5.0"
TMP_DEB="/tmp/lmstudio_latest.deb"
TMP_HEAD="$(mktemp --suffix=.deb)"
trap 'rm -f "$TMP_HEAD" "$TMP_DEB"' EXIT
# LM Studio ships its launcher icon under hicolor/0x0/apps -- an invalid size
# bucket the icon theme ignores -- so the app installs with no icon, and every
# release so far packages it the same way. Mirror the package's icon into a
# valid per-user bucket and refresh the cache. Kept under ~/.local so apt
# upgrades never clobber it; re-copied only when missing or when it changed.
ensure_icon() {
local pkg_icon="/usr/share/icons/hicolor/0x0/apps/lm-studio.png"
local hicolor="$HOME/.local/share/icons/hicolor"
local user_icon="$hicolor/512x512/apps/lm-studio.png"
[ -f "$pkg_icon" ] || return 0
cmp -s "$pkg_icon" "$user_icon" && return 0
mkdir -p "$(dirname "$user_icon")"
cp -f "$pkg_icon" "$user_icon"
[ -f "$hicolor/index.theme" ] || cp /usr/share/icons/hicolor/index.theme "$hicolor/index.theme" 2>/dev/null || true
gtk-update-icon-cache -f -q "$hicolor" 2>/dev/null || true
echo "Refreshed LM Studio launcher icon -> $user_icon"
}
echo "Resolving latest LM Studio download URL..."
deb_url=$(curl -fsSL -A "$UA" -o /dev/null -w '%{url_effective}' "$URL") || deb_url=""
if [ -z "$deb_url" ]; then
echo "Could not resolve the LM Studio download URL from $URL" >&2
exit 1
fi
echo "Latest .deb: $deb_url"
# The .deb is ~600 MB and the version in its filename (e.g. 0.4.14-4) is not the
# string dpkg records (e.g. 0.4.14+4), so the two cannot be compared directly.
# Read the real Version from the package's own control metadata, fetching only
# the front of the file -- the small control.tar.* member precedes the large
# data.tar.* -- so an up-to-date install is detected without downloading ~600 MB.
echo "Reading candidate version from package metadata..."
curl -fsSL -A "$UA" -r 0-2097151 "$deb_url" -o "$TMP_HEAD"
control_member=$(ar t "$TMP_HEAD" 2>/dev/null | grep -m1 '^control\.tar' || true)
if [ -z "$control_member" ]; then
echo "Could not find the control member in the downloaded .deb header." >&2
exit 1
fi
case "$control_member" in
*.gz) decomp="gzip -dc" ;;
*.xz) decomp="xz -dc" ;;
*.zst) decomp="zstd -dc" ;;
*.bz2) decomp="bzip2 -dc" ;;
*) decomp="cat" ;;
esac
latest=$(ar p "$TMP_HEAD" "$control_member" 2>/dev/null | $decomp 2>/dev/null | tar -xO ./control 2>/dev/null | sed -n 's/^Version: *//p') || true
if [ -z "$latest" ]; then
echo "Could not read Version from the package control metadata." >&2
exit 1
fi
installed=$(dpkg-query -W -f='${Version}' "$PKG" 2>/dev/null || echo "")
if [ "$installed" = "$latest" ]; then
echo "LM Studio is already up to date ($installed)."
ensure_icon
exit 0
fi
echo "Updating LM Studio ${installed:-(none)} -> $latest"
echo "Downloading $deb_url ..."
curl -fL -A "$UA" "$deb_url" -o "$TMP_DEB"
echo "Installing LM Studio..."
sudo dpkg -i "$TMP_DEB"
ensure_icon
echo "LM Studio updated successfully to $latest!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment