From 9dfee100d2e88312d2f15444daee695c2fc34ca7 Mon Sep 17 00:00:00 2001 From: Muhammad Aizat Date: Sun, 13 Sep 2026 02:45:04 +0800 Subject: [PATCH] v0.7.3: work out the user bus instead of asking for it by hand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A shell entered via `su` keeps the ORIGINAL user's XDG_RUNTIME_DIR, so `systemctl --user` hunts for the bus in someone else's directory and finds nothing — even when this user's manager is running perfectly. v0.7.2 detected that and told the operator to export the right path. Typing /run/user/100 instead of /run/user/1000 cost a whole run. The runtime dir is /run/user/ by definition. The script now derives it, retries the bus check with it, and installs the units — then tells the operator to export it for the REST of their shell, because a child process cannot fix its parent's environment. The failure message also stopped guessing. It now distinguishes the two real cases: /run/user/ missing (no logind session — enable-linger, and no fresh login is needed, contrary to what v0.7.1 said) versus present but unanswered (the manager itself is the problem — go look at user@.service). Four branches fired in a sandbox with three stub systemctls: bus answers directly; bus answers only with the corrected dir; runtime dir absent; runtime dir present but manager silent. All exit 0, and the middle one installs units that the previous version would have skipped. Co-Authored-By: Claude Opus 5 (1M context) --- install.sh | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index 47bb5a0..4303570 100755 --- a/install.sh +++ b/install.sh @@ -79,8 +79,31 @@ say "systemd user units" # "Failed to connect to user scope bus". Ask the real question — can we talk to # the user manager — instead of asking whether the binary exists. USER_BUS="" -if command -v systemctl >/dev/null 2>&1 && systemctl --user show-environment >/dev/null 2>&1; then - USER_BUS="yes" +BUS_FIXED_UP="" +if command -v systemctl >/dev/null 2>&1; then + if systemctl --user show-environment >/dev/null 2>&1; then + USER_BUS="yes" + else + # A shell entered via `su` keeps the ORIGINAL user's XDG_RUNTIME_DIR, so + # `systemctl --user` looks for the bus in someone else's directory and finds + # nothing — even when this user's manager is running perfectly well. The + # runtime dir is /run/user/ by definition, so work it out instead of + # asking someone to export it by hand and get the digits right. + _own_runtime="/run/user/$(id -u)" + if [[ -d "$_own_runtime" && "${XDG_RUNTIME_DIR:-}" != "$_own_runtime" ]]; then + export XDG_RUNTIME_DIR="$_own_runtime" + if systemctl --user show-environment >/dev/null 2>&1; then + USER_BUS="yes" + BUS_FIXED_UP="yes" + fi + fi + fi +fi + +if [[ -n "$BUS_FIXED_UP" ]]; then + ok "user bus found at $XDG_RUNTIME_DIR (the inherited XDG_RUNTIME_DIR pointed elsewhere)" + warn "this shell still has the old value. For later commands in THIS shell:" + warn " export XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" fi if [[ -z "$USER_BUS" ]]; then @@ -89,8 +112,13 @@ if [[ -z "$USER_BUS" ]]; then warn "reason: systemctl is not on PATH." else warn "reason: systemctl --user cannot reach a user manager (XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-unset})." - warn "common causes: an LXC without logind, a shell entered via su, or no lingering." - warn " sudo loginctl enable-linger $USER # then log in fresh and re-run" + if [[ ! -d "/run/user/$(id -u)" ]]; then + warn "/run/user/$(id -u) does not exist — $USER has no logind session at all." + warn " sudo loginctl enable-linger $USER # then re-run; no fresh login needed" + else + warn "/run/user/$(id -u) exists but the manager there did not answer." + warn " systemctl status user@$(id -u).service # start here" + fi fi warn "until then, run the three by hand from $REPO:" warn " $VENV/bin/socialmag-openbridge &"