Skip to content

Instantly share code, notes, and snippets.

@PhrozenByte
Last active September 24, 2025 11:46
Show Gist options
  • Save PhrozenByte/8d481dd5c6668adbe1882eee4cc00506 to your computer and use it in GitHub Desktop.
Save PhrozenByte/8d481dd5c6668adbe1882eee4cc00506 to your computer and use it in GitHub Desktop.
Runs the 'org.chromium.Chromium' Flatpak with file forwarding enabled, and support for named and temporary Chromium profiles.
#!/bin/bash
##
# Run org.chromium.Chromium with file forwarding and temp profiles
#
# This wrapper script runs the 'org.chromium.Chromium' Flatpak and
# transparently adds the following options to Chromium's CLI:
# - Flatpak's `-u`, `--user`, `--system`, `--installation=NAME`, `--arch`,
# `--branch`, `--file-forwarding`, and `--verbose` options are passed to
# Flatpak; refer to flatpak-run(1) for details about these options
# - `--user-data-dir=NAME` additionally accepts existing user data directories
# matching `~/.var/app/org.chromium.Chromium/config/chromium.NAME`; to use a
# user data directory in the current working directory, pass a relative path
# like `./NAME` instead; use `--user-data-dir=default` to load Chromium's
# default profile
# - `--temp-profile` allows running Chromium with a temporary profile that is
# automatically disposed after closing Chromium; if no `--user-data-dir` is
# given, `--temp-profile` is implied; pass `--no-temp-profile` to disable
# this behaviour; if both `--temp-profile` and `--user-data-dir` are passed,
# a temporary copy of the given user data directory will be used instead of
# using a fresh profile; when passing an user data directory stored in
# `~/.var/app/org.chromium.Chromium/config` its cache will be copied, too
# - `--verbose` additionally prints the commands this wrapper executes
#
# Copyright (C) 2025 Daniel Rudolf (<https://www.daniel-rudolf.de>)
# License: The MIT License <http://opensource.org/licenses/MIT>
#
# SPDX-License-Identifier: MIT
set -eu -o pipefail
# helper functions
quote() {
local QUOTED=
for ARG in "$@"; do
[ "$(printf '%q' "$ARG")" == "$ARG" ] \
&& QUOTED+=" $ARG" \
|| QUOTED+=" ${ARG@Q}"
done
echo "${QUOTED:1}"
}
cmd() {
[ "$VERBOSE" != "y" ] || echo + "$(quote "$@")" >&2
"$@"
}
# check script dependencies
[ -x "$(which flatpak 2> /dev/null)" ] \
|| { echo "Missing script dependency: flatpak" >&2; exit 1 ; }
[ -x "$(which realpath 2> /dev/null)" ] \
|| { echo "Missing script dependency: realpath" >&2; exit 1; }
[[ "$(realpath --version | head -n1)" == "realpath (GNU coreutils) "* ]] \
|| { echo "Missing script dependency: GNU coreutils" >&2; exit 1; }
# read parameters
FLATPAK="org.chromium.Chromium"
FLATPAK_ARGS=()
FLATPAK_BRANCH=""
FILE_FORWARDING=""
CHROMIUM_ARGS=()
TEMP_PROFILE=""
USER_DATA_DIR=""
USER_CACHE_DIR=""
VERBOSE=""
while [ $# -gt 0 ]; do
case "$1" in
-u|--user|--system|--installation=*|--arch=*)
FLATPAK_ARGS+=( "$1" )
shift
;;
--branch=*)
FLATPAK_BRANCH="${1:9}"
shift
;;
--file-forwarding)
FILE_FORWARDING="y"
shift
;;
--temp-profile)
TEMP_PROFILE="y"
shift
;;
--no-temp-profile)
TEMP_PROFILE="n"
shift
;;
--user-data-dir=*)
USER_DATA_DIR="${1:16}"
shift
;;
--verbose)
VERBOSE="y"
shift
;;
--)
CHROMIUM_ARGS+=( "$@" )
set --
;;
*)
CHROMIUM_ARGS+=( "$1" )
shift
;;
esac
done
# check Flatpak installation
[ "$VERBOSE" != "y" ] || echo + "flatpak info $(quote "${FLATPAK_ARGS[@]}" "$FLATPAK")" >&2
flatpak info "${FLATPAK_ARGS[@]}" "$FLATPAK" >/dev/null 2>&1 \
|| { echo "Flatpak ${FLATPAK@Q} not installed" >&2; exit 1; }
[ -d "$HOME/.var/app/$FLATPAK/config" ] \
|| { echo "Flatpak ${FLATPAK@Q} wasn't initialized for the current user yet" >&2; exit 1; }
# parse Flatpak's --branch, --file-forwarding, and --verbose options
[ -z "$FLATPAK_BRANCH" ] || FLATPAK_ARGS+=( --branch="$FLATPAK_BRANCH" )
[ "$FILE_FORWARDING" != "y" ] || FLATPAK_ARGS+=( --file-forwarding )
[ "$VERBOSE" != "y" ] || FLATPAK_ARGS+=( --verbose )
# parse Chromium's --user-data-dir and --temp-profile options
if [ -z "$TEMP_PROFILE" ]; then
[ -n "$USER_DATA_DIR" ] && TEMP_PROFILE="n" || TEMP_PROFILE="y"
fi
if [ -n "$USER_DATA_DIR" ]; then
if [[ "$USER_DATA_DIR" != */* ]]; then
USER_DATA_NAME="$USER_DATA_DIR"
if [ "$USER_DATA_NAME" == "default" ]; then
USER_DATA_DIR="$HOME/.var/app/$FLATPAK/config/chromium"
USER_CACHE_DIR="$HOME/.var/app/$FLATPAK/cache/chromium"
else
USER_DATA_DIR="$HOME/.var/app/$FLATPAK/config/chromium.$USER_DATA_NAME"
USER_CACHE_DIR="$HOME/.var/app/$FLATPAK/cache/chromium.$USER_DATA_NAME"
fi
[ -e "$USER_DATA_DIR" ] || { echo "Invalid named user data directory ${USER_DATA_NAME@Q}" \
"at ${USER_DATA_DIR@Q}: No such file or directory" >&2; exit 1; }
[ -d "$USER_DATA_DIR" ] || { echo "Invalid named user data directory ${USER_DATA_NAME@Q}" \
"at ${USER_DATA_DIR@Q}: Not a directory" >&2; exit 1; }
[ ! -e "$USER_CACHE_DIR" ] || [ -d "$USER_CACHE_DIR" ] || { echo "Invalid cache directory of named" \
"user data directory ${USER_DATA_NAME@Q} at ${USER_CACHE_DIR@Q}: Not a directory" >&2; exit 1; }
elif [ -e "$USER_DATA_DIR" ]; then
[ -d "$USER_DATA_DIR" ] || { echo "Invalid user data directory ${USER_DATA_DIR@Q}:" \
"Not a directory" >&2; exit 1; }
ACTUAL_USER_DATA_DIR_PARENT="$(realpath "$(dirname "$USER_DATA_DIR")")"
EXPECTED_USER_DATA_DIR_PARENT="$(realpath "$HOME/.var/app/$FLATPAK/config")"
if [ "$ACTUAL_USER_DATA_DIR_PARENT" == "$EXPECTED_USER_DATA_DIR_PARENT" ]; then
USER_DATA_DIR="$HOME/.var/app/$FLATPAK/config/$(basename "$USER_DATA_DIR")"
USER_CACHE_DIR="$HOME/.var/app/$FLATPAK/cache/$(basename "$USER_DATA_DIR")"
[ ! -e "$USER_CACHE_DIR" ] || [ -d "$USER_CACHE_DIR" ] || { echo "Invalid cache directory of" \
"given user data directory at ${USER_CACHE_DIR@Q}: Not a directory" >&2; exit 1; }
fi
fi
fi
if [ "$TEMP_PROFILE" == "y" ]; then
TEMP_USER_DATA_DIR="$(cmd mktemp -d "$HOME/.var/app/$FLATPAK/config/chromium.XXXXXXXXXX")"
TEMP_USER_CACHE_DIR="$HOME/.var/app/$FLATPAK/cache/$(basename "$TEMP_USER_DATA_DIR")"
trap "cmd rm -rf ${TEMP_USER_DATA_DIR@Q} ${TEMP_USER_CACHE_DIR@Q}" EXIT
[ -z "$USER_DATA_DIR" ] || [ ! -e "$USER_DATA_DIR" ] \
|| cmd cp -a -T "$USER_DATA_DIR" "$TEMP_USER_DATA_DIR"
[ -z "$USER_CACHE_DIR" ] || [ ! -e "$USER_CACHE_DIR" ] \
|| cmd cp -a "$USER_CACHE_DIR" "$TEMP_USER_CACHE_DIR"
USER_DATA_DIR="$TEMP_USER_DATA_DIR"
USER_CACHE_DIR="$TEMP_USER_CACHE_DIR"
fi
if [ -n "$USER_DATA_DIR" ]; then
CHROMIUM_ARGS=( --user-data-dir="$USER_DATA_DIR" "${CHROMIUM_ARGS[@]}" )
fi
# run Chromium Flatpak
cmd flatpak run --command=/app/bin/chromium "${FLATPAK_ARGS[@]}" \
"$FLATPAK" "${CHROMIUM_ARGS[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment