Skip to content

Instantly share code, notes, and snippets.

@x43x61x69
Last active March 17, 2026 00:54
Show Gist options
  • Select an option

  • Save x43x61x69/9a5a231a25426e8a2cc0f7c24cfdaed9 to your computer and use it in GitHub Desktop.

Select an option

Save x43x61x69/9a5a231a25426e8a2cc0f7c24cfdaed9 to your computer and use it in GitHub Desktop.
Steam Deck VNC Installation
#!/bin/bash
#
# Script for installing x11vnc on Steam Deck.
#
# Install:
#
# sh -c "$(curl -fsSL https://gist.githubusercontent.com/x43x61x69/9a5a231a25426e8a2cc0f7c24cfdaed9/raw/vnc_install.sh?$RANDOM)"
#
# This will modify root filesystem so it will probably get
# overwrite on system updates but is totally ok executing
# it several times, so if something stops working just
# launch it again.
#
# If you like seeing the terminal window, change
# "Terminal=false" to "Terminal=true" for the desktop entries below.
#
# Original script: àngel "mussol" bosch (muzzol@gmail.com)
#
echo -n "Checking root permissions: "
if [ "$(id -ru)" == "0" ]; then
echo "OK"
else
echo "user is $(whoami), trying again as root"
exec sudo sh -c "$(curl -fsSL https://gist.githubusercontent.com/x43x61x69/9a5a231a25426e8a2cc0f7c24cfdaed9/raw/vnc_install.sh?$RANDOM)"
exit 0
fi
## system related comands
echo "Disabling readonly filesystem"
steamos-readonly disable
if [ ! -e "/etc/pacman.d/gnupg/trustdb.gpg" ]; then
echo "Initalizing pacman keys"
pacman-key --init
pacman-key --populate archlinux
fi
echo "Installing package"
pacman -Sy --noconfirm x11vnc
echo "Re-enabling readonly filesystem"
steamos-readonly enable
## user related commands
DECK_USER=$(grep "^User=" /etc/sddm.conf.d/steamos.conf | cut -d"=" -f2)
echo "Creating desktop entries"
mkdir -p "/home/${DECK_USER}/Desktop/VNC/"
LAUNCHER_TEXT='[Desktop Entry]
Name=Start VNC
Exec=x11vnc -noxdamage -usepw -display :0 -no6 -forever -bg
Icon=/usr/share/app-info/icons/archlinux-arch-community/64x64/x11vnc_computer.png
Terminal=false
Type=Application
StartupNotify=false'
echo "$LAUNCHER_TEXT" > "/home/${DECK_USER}/Desktop/VNC/Start VNC.desktop"
chown "${DECK_USER}" "/home/${DECK_USER}/Desktop/VNC/Start VNC.desktop"
chmod +x "/home/${DECK_USER}/Desktop/VNC/Start VNC.desktop"
LAUNCHER_TEXT='[Desktop Entry]
Name=Stop VNC
Exec=killall x11vnc
Icon=/usr/share/app-info/icons/archlinux-arch-community/64x64/x11vnc_computer.png
Terminal=false
Type=Application
StartupNotify=false'
echo "$LAUNCHER_TEXT" > "/home/${DECK_USER}/Desktop/VNC/Stop VNC.desktop"
chown "${DECK_USER}" "/home/${DECK_USER}/Desktop/VNC/Stop VNC.desktop"
chmod +x "/home/${DECK_USER}/Desktop/VNC/Stop VNC.desktop"
LAUNCHER_TEXT='[Desktop Entry]
Name=Set VNC Password
Exec=sudo x11vnc -storepasswd; read -s -n 1 -p "Press any key to continue . . ."
Icon=/usr/share/app-info/icons/archlinux-arch-community/64x64/x11vnc_computer.png
Terminal=true
Type=Application
StartupNotify=false'
echo "$LAUNCHER_TEXT" > "/home/${DECK_USER}/Desktop/VNC/Set VNC Password.desktop"
chown "${DECK_USER}" "/home/${DECK_USER}/Desktop/VNC/Set VNC Password.desktop"
chmod +x "/home/${DECK_USER}/Desktop/VNC/Set VNC Password.desktop"
LAUNCHER_TEXT='[Desktop Entry]
Name=Reinstall VNC
Exec=sudo sh -c "$(curl -fsSL https://gist.githubusercontent.com/x43x61x69/9a5a231a25426e8a2cc0f7c24cfdaed9/raw/vnc_install.sh?$RANDOM)"
Icon=/usr/share/app-info/icons/archlinux-arch-community/64x64/x11vnc_computer.png
Terminal=true
Type=Application
StartupNotify=false'
echo "$LAUNCHER_TEXT" > "/home/${DECK_USER}/Desktop/VNC/Reinstall VNC.desktop"
chown "${DECK_USER}" "/home/${DECK_USER}/Desktop/VNC/Reinstall VNC.desktop"
chmod +x "/home/${DECK_USER}/Desktop/VNC/Reinstall VNC.desktop"
SCRIPT_TEXT='#!/bin/bash
x11vnc -noxdamage -usepw -display :0 -no6 -forever -bg'
echo "$SCRIPT_TEXT" > "/home/${DECK_USER}/Desktop/VNC/vnc_startup.sh"
chown "${DECK_USER}" "/home/${DECK_USER}/Desktop/VNC/vnc_startup.sh"
chmod +x "/home/${DECK_USER}/Desktop/VNC/vnc_startup.sh"
if [ ! -f "/home/${DECK_USER}/.vnc/passwd" ]; then
echo "Creating VNC password"
sudo -H -u "${DECK_USER}" bash -c "x11vnc -storepasswd"
fi
echo "Done!"
read -s -n 1 -p "Press any key to continue . . ."
echo ""
@ch4d1
Copy link

ch4d1 commented Mar 3, 2024

I have occasionally encountered the issue that the DisplayID was not "0". To resolve this issue, I modified the 'vnc_startup.sh' script. Now, it always retrieves and uses the current ID.

  • vnc_startup.sh
#!/bin/bash
display_id=$(who | grep "pts/0" | sed -n 's/.*(\(:[0-9]\)).*/\1/p' | tr -d ':')
x11vnc -noxdamage -usepw -display :$display_id -no6 -forever -bg

@TFWol
Copy link

TFWol commented Apr 14, 2024

@ch4d1 Nice

@ryanhendry
Copy link

Outside of the script I had to run

sudo steamos-readonly disable
sudo pacman-key --populate holo
sudo steamos-readonly enable

And then ran the script again. I also ran this, but am not sure if it helped or not

sudo rm -rf /etc/pacman.d/gnupg

@JimWas
Copy link

JimWas commented Sep 30, 2024

Been trying everything to get x11vnc installed but always end up with

:: Synchronizing package databases...
error: failed to synchronize all databases (unable to lock database)
Re-enabling readonly filesystem

Any fixes for Sept 2024?

@nicodemus144
Copy link

Thanks @edasque I was facing the same error and sudo pacman-key --populate holo resolved it for me 👍

this was sufficient for me to install VNC today. thank you!

@cheako
Copy link

cheako commented Jul 25, 2025

please replace some of the above, from xone_install_or_update.sh(I fixed up some things, though), with...

# Check if the user has sudo privileges
# If not, prompt the user for a password
if ! sudo -n true 2>/dev/null; then
    if ! zenity --password --title="Sudo password" | eval sudo -S echo "" "$REDIRECT"; then
        zenity --error --text="Sorry, you need to have sudo privileges to run this script." --title="Error"
        exit 1
    fi
fi

# If output of `sudo steamos-readonly status` is "enabled", disable it
if [[ "$(sudo steamos-readonly status)" = "enabled" ]]; then
    sudo steamos-readonly disable
    KEEP_READ_ONLY="true"
fi

# If pacman-key is not initialised, initialise it
if ! eval pacman-key --list-keys >/dev/null 2>&1; then
    echo -e "\e[1mInitialising pacman...\e[0m"
    echo ""
    sudo pacman-key --init
fi

echo "Refreshing pacman keys..."
# Always populate archlinux and holo keys, quick enough to do every time
# TODO: Only populate if not already populated
sudo pacman-key --populate archlinux holo >/dev/null 2>&1
# Re enable steamos-readonly if it was enabled before
if [[ $KEEP_READ_ONLY = "true" ]]; then
    sudo steamos-readonly enable
fi

@nullm0ose
Copy link

For those running into the issue of the script throwing XOpenDisplay(":0") failed. error

I ran into this issue when running the script via ssh. The script initializes VNC & needs to communicate with the physical display in the current shell session, so running this via ssh will fail.

I ran the script directly on the deck and it ran w/ no issues.

@cheako
Copy link

cheako commented Mar 17, 2026

This script is really broken. Firstly even though == does seem to work everywhere, it's not documented anywhere. [ in an alias for /bin/test and the shell runs a command and it wouldn't be out of the question for a rust rewrite of test to not have == and make it's way onto the steamdeck, while in bash [[ is a shell builtin and mainly does the same things... Bash's [[ doesn't document =, but the test builtin does. However if you look at line 21, that should be -eq and not the "documented" = as these are for numbers and strings respectively, see the test man page and help [[ from bash.

I tried my best to suggest fixes to this script, but I think the author is AFK.

@nullm0ose
Copy link

Strange... I needed to quickly spin up a vnc server on my Steam Deck and came across this gist from a google search and installed it with no issues whatsoever. Nothing modified in anyway. Just uninstalled everything and re-ran it again from scratch just to be sure.

PGP Key Prep

sudo steamos-readonly disable
sudo pacman-key --populate holo

Pull gist

sh -c "$(curl -fsSL https://gist.githubusercontent.com/x43x61x69/9a5a231a25426e8a2cc0f7c24cfdaed9/raw/vnc_install.sh?$RANDOM)"

Then on Steam Deck in desktop mode, run script in Konsole. Running script via ssh will fail. Script reads active display from current shell session

./vnc_startup.sh

My Steam Deck is more or less stock with the exception of some utilities like Tailscale or Decky Loader. I just installed the latest update and even confirmed that vnc persists even after updates are installed.

@x43x61x69
Copy link
Author

Sorry all, I sold my SteamDeck long ago thus unable to maintain this script anymore. Glad to see the community keeps improving it and make it working for newer SteamOS versions.

This script is really broken. Firstly even though == does seem to work everywhere, it's not documented anywhere. [ in an alias for /bin/test and the shell runs a command and it wouldn't be out of the question for a rust rewrite of test to not have == and make it's way onto the steamdeck, while in bash [[ is a shell builtin and mainly does the same things... Bash's [[ doesn't document =, but the test builtin does. However if you look at line 21, that should be -eq and not the "documented" = as these are for numbers and strings respectively, see the test man page and help [[ from bash.

I tried my best to suggest fixes to this script, but I think the author is AFK.

Sorry y’all, I sold my SteamDeck long ago thus unable to maintain this script anymore. Glad to see the community keeps improving it and make it working for newer SteamOS versions.

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