Skip to content

Instantly share code, notes, and snippets.

@Vovan-VE
Last active February 27, 2021 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vovan-VE/6c47968b19ff43512f56de9b41a432d9 to your computer and use it in GitHub Desktop.
Save Vovan-VE/6c47968b19ff43512f56de9b41a432d9 to your computer and use it in GitHub Desktop.
Browser launcher to reuse already running browsers before start new one
#!/bin/bash
################################################################################
# This launcher will proxy arguments to one of already running browsers,
# or will run new browser.
################################################################################
#
# I currently use two browsers. First primary (Opera) is for work, and it's full
# of opened tabs. Second (Vivaldi) is for any another things when First is not
# running I just don't want to start it with all of it's opened tabs.
#
# However, since First browser is primary in OS, "opening in browser" any link
# from another program will start First browser when it's not, but Second is
# running. This may be slow and will eat some extra RAM, when I don't want it.
#
# Here we go. This launcher solves the problem. I declared browsers in order I
# prefer, and it will try to use already running browser at first before running
# new browser.
#
# This launcher is relying to browsers own mechanism to prevent multiple
# instances running by cross-process communication. All tabbed browser have such
# ability.
#
################################################################################
# Your available and wanted browsers in order. First is most preferrable.
# Each item must be a valid executable binary available in your $PATH
BROWSERS=( opera vivaldi )
# Map executable binaries for "is running" check.
# They may be different from `which "$NAME"` due to symlinks
# or internal binaries structuring (like Vivaldi has separate launcher inside).
# Each binary name must be exactly equal to alctually running executable full
# file name with path. This full filename must be searchable with `pgrep` and
# be unambiguous to not mess with other processes, like `opera` may match
# unwanted `operation`.
declare -A BROWSERS_BIN_RUNNING=(
[opera]=/usr/lib/x86_64-linux-gnu/opera/opera
[vivaldi]=/opt/vivaldi/vivaldi-bin
)
ME="$( basename "$0" )"
echo "$ME: search running browser in order" >&2
for NAME in "${BROWSERS[@]}"; do
# find binary path to start new instance
BIN_START="$( which "$NAME" )" || {
echo "$ME: which '$NAME' - error; check if '$NAME' is correct and installed" >&2
echo "$ME: check if BROWSERS are correct" >&2
exit 1
}
# if it's executable?
if ! [ -x "$BIN_START" ]; then
echo "$ME: '$NAME' is not executable - $BIN_START" >&2
echo "$ME: check if BROWSERS are correct" >&2
exit 1
fi
# binary full filename to check if it's running
BIN_RUNNING="${BROWSERS_BIN_RUNNING[$NAME]}"
# if it's executable?
if ! [ -x "$BIN_RUNNING" ]; then
echo "$ME: '$NAME's bin to check is not executable - $BIN_RUNNING" >&2
echo "$ME: check if BROWSERS_BIN_RUNNING is correct" >&2
exit 1
fi
# search anready running processes, ignore output and deal with exit code
pgrep -f "^$BIN_RUNNING(\$| )" > /dev/null
ST=$?
case $ST in
# found some processes
0)
echo "$ME: '$NAME' is running - $BIN_RUNNING" >&2
echo "$ME: passing arguments to '$NAME'" >&2
"$BIN_START" "$@" & > /dev/null 2>&1
exit 0
;;
# no processes was found
1)
echo "$ME: '$NAME' isn't running - $BIN_RUNNING" >&2
;;
# error with `pgrep`
*)
echo "$ME: error from `pgrep` on '$NAME's bin - $BIN_RUNNING" >&2
exit 2
;;
esac
done
echo "$ME: no running browser found, run new" >&2
for NAME in "${BROWSERS[@]}"; do
echo "$ME: passing arguments to '$NAME'" >&2
"$NAME" "$@" & > /dev/null 2>&1
exit 0
done
echo "$ME: no browsers declared" >&2
exit 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment