Files
linux-on-android-without-root/provision/init-phone.sh
T
StefanandClaude Opus 5 7d0063278c Upgrade-Abbrüche abfangen und das Rauschen filtern
Beim Wechsel der Python-Version wirft dpkg dutzende Zeilen 'unable to delete old
directory ... Directory not empty'. Das sind Warnungen — in site-packages liegen
noch .pyc-Dateien oder selbst installierte Module. Sie verdecken aber die eine
Zeile, auf die es ankommt, und werden deshalb gefiltert.

Bricht das Upgrade ab, steckt dpkg meist halb fertig fest und blockiert jede
weitere Installation. Beide Skripte versuchen jetzt 'dpkg --configure -a' und
'apt-get -f install', dann das Upgrade erneut, bevor sie aufgeben. Scheitert es
weiterhin, nennen sie den Befehl, der den echten Fehler ohne Rauschen zeigt.

Dazu eine Platzprüfung im Bootstrap gegen $PREFIX statt gegen /. In Termux zeigt
'df -h' als / die Systempartition mit oft nur zweistelligen MB — die aber nichts
mit dem Platz zu tun hat, der Termux zur Verfügung steht. Wer danach geht,
diagnostiziert am falschen Datenträger.

Der Vulkan-Treiber ist geklärt: mesa-vulkan-icd-freedreno ist verfügbar und steht
in der Kandidatenliste bereits an erster Stelle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 21:50:18 +02:00

198 lines
8.7 KiB
Bash
Executable File

#!/data/data/com.termux/files/usr/bin/bash
# HPOS — Startpunkt auf dem Telefon.
#
# Dieses Skript ist absichtlich das EINZIGE, was per adb aufs Telefon kommt.
# Alles Weitere holt es sich per git. Der Grund: danach ist das Repo auf dem
# Telefon eine Arbeitskopie, keine Kopie. Aktualisieren heißt dann schlicht
#
# cd ~/hpos && git pull
#
# statt jedes Mal wieder den PC anzuwerfen und Dateien zu schieben.
#
# Aufruf in Termux:
# bash /sdcard/hpos-init.sh
# bash /sdcard/hpos-init.sh https://beispiel/anderes-repo.git
set -uo pipefail
REPO="${1:-${HPOS_REPO:-@@REPO_URL@@}}"
ZIEL="$HOME/hpos"
if [ -t 1 ]; then
C_OK=$'\033[32m'; C_WARN=$'\033[33m'; C_ERR=$'\033[31m'
C_HEAD=$'\033[1;36m'; C_DIM=$'\033[2m'; C_OFF=$'\033[0m'
else
C_OK=""; C_WARN=""; C_ERR=""; C_HEAD=""; C_DIM=""; C_OFF=""
fi
kopf() { printf '\n%s══ %s ══%s\n' "$C_HEAD" "$*" "$C_OFF"; }
ok() { printf '%s ✓%s %s\n' "$C_OK" "$C_OFF" "$*"; }
warn() { printf '%s !%s %s\n' "$C_WARN" "$C_OFF" "$*"; }
fehl() { printf '%s ✗%s %s\n' "$C_ERR" "$C_OFF" "$*"; }
hinweis() { printf '%s %s%s\n' "$C_DIM" "$*" "$C_OFF"; }
case "$REPO" in
@@*) fehl "Keine Repo-Adresse hinterlegt."
hinweis "Aufruf mit Adresse: bash /sdcard/hpos-init.sh <url>"
exit 1 ;;
esac
# Benutzernamen aus der Adresse entfernen. Lesen geht anonym; steht ein Name in
# der URL, fragt git trotzdem nach einem Passwort — auf einer Bildschirmtastatur
# eine unnötige Quälerei. Zum Schreiben braucht man ihn ohnehin nur auf dem PC.
REPO_ROH="$REPO"
REPO=$(printf '%s' "$REPO" | sed -E 's#^(https?://)[^/@]+@#\1#')
[ "$REPO" != "$REPO_ROH" ] && ANONYM=1 || ANONYM=0
kopf "HPOS — Ersteinrichtung auf dem Telefon"
hinweis "Repo: $REPO"
[ "$ANONYM" = 1 ] && hinweis "(Benutzername entfernt — gelesen wird anonym)"
# ── Vollupgrade ──────────────────────────────────────────────────────────────
# Muss VOR jedem anderen Paket laufen. Termux verträgt keine Teilupgrades: die
# Pakete werden gegeneinander gebaut, und ein einzeln nachinstalliertes trifft
# sonst auf veraltete Abhängigkeiten. Genau daran ist proot-distro gescheitert —
# es trug die Shebang-Zeile python3.13, während eine andere Fassung installiert war.
#
# Überspringbar mit HPOS_OHNE_UPGRADE=1, etwa bei knappem Datenvolumen.
kopf "Termux auf einen Stand bringen"
if [ "${HPOS_OHNE_UPGRADE:-0}" = 1 ]; then
warn "Übersprungen (HPOS_OHNE_UPGRADE=1)"
hinweis "Bei Problemen mit proot-distro ist das die erste Stelle zum Nachsehen."
else
hinweis "Das dauert und lädt einiges. Es erspart aber genau die Fehler,"
hinweis "die sonst erst Stunden später als kaputtes proot-distro auffallen."
export DEBIAN_FRONTEND=noninteractive
# Beim Wechsel der Python-Version wirft dpkg dutzende Zeilen
# "unable to delete old directory ... Directory not empty". Das sind
# Warnungen, keine Fehler: in site-packages liegen noch .pyc-Dateien oder
# selbst installierte Module. Sie herauszufiltern ist kein Verstecken —
# sie verdecken sonst die eine Zeile, auf die es ankommt.
rauschfilter() { grep -viE 'unable to delete old directory|^(Unpacking|Preparing|Selecting) '; }
# --force-confold: vorhandene Konfiguration behalten, statt mitten im Lauf
# eine Rückfrage zu stellen, die niemand beantwortet.
pkg update -y 2>&1 | rauschfilter
if pkg upgrade -y -o Dpkg::Options::=--force-confold 2>&1 | rauschfilter; then
ok "Termux ist aktuell"
else
warn "Das Upgrade brach ab. Versuche zu reparieren …"
# Die übliche Ursache ist ein einzelnes Paket, das sich nicht auspacken
# ließ. Danach steckt dpkg halb fertig fest und blockiert alles Weitere.
dpkg --configure -a 2>&1 | rauschfilter
apt-get -f install -y 2>&1 | rauschfilter
if pkg upgrade -y -o Dpkg::Options::=--force-confold 2>&1 | rauschfilter; then
ok "Nach der Reparatur durchgelaufen"
else
warn "Bleibt unvollständig."
hinweis "Speicherplatz prüfen: df -h \$PREFIX"
hinweis "Fehler ohne Rauschen ansehen:"
hinweis " pkg upgrade -y 2>&1 | grep -viE 'unable to delete' | tail -20"
hinweis "Weiter geht es trotzdem — aber hier ansetzen, falls später etwas klemmt."
fi
fi
fi
# ── git ──────────────────────────────────────────────────────────────────────
kopf "git"
if command -v git >/dev/null 2>&1; then
ok "bereits vorhanden ($(git --version))"
else
if pkg install -y git; then ok "installiert"
else fehl "Installation von git fehlgeschlagen"; exit 1; fi
fi
# Das Telefon liest nur. Es soll nie versehentlich versuchen zurückzuschreiben —
# ein Push von hier wäre weder gewollt noch möglich.
git config --global credential.helper "" 2>/dev/null || true
# ── Rückfallebene: Archiv statt Klon ─────────────────────────────────────────
# Gitea, Forgejo und GitHub bieten den Baum zusätzlich als Tarball an. Der Weg
# dorthin geht nicht über upload-pack und funktioniert deshalb auch dann noch,
# wenn der Klon am Server scheitert. Das Ergebnis ist aber nur ein Abzug: kein
# .git, kein 'git pull'. Es ist eine Notlösung, keine Alternative.
archiv_holen() {
local basis zweig="${HPOS_ZWEIG:-main}" url tmp
basis="${REPO%.git}"
command -v curl >/dev/null 2>&1 || pkg install -y curl >/dev/null 2>&1
command -v tar >/dev/null 2>&1 || pkg install -y tar >/dev/null 2>&1
tmp=$(mktemp -d)
for url in "$basis/archive/$zweig.tar.gz" \
"$basis/archive/refs/heads/$zweig.tar.gz"; do
hinweis "Versuche Archiv: $url"
if curl -sfL -o "$tmp/a.tar.gz" "$url" && tar tzf "$tmp/a.tar.gz" >/dev/null 2>&1; then
mkdir -p "$ZIEL"
# --strip-components=1: die Archive enthalten alles unter einem
# Wurzelverzeichnis, das wir nicht mit übernehmen wollen.
if tar xzf "$tmp/a.tar.gz" -C "$ZIEL" --strip-components=1; then
rm -rf "$tmp"
ok "Archiv entpackt nach $ZIEL"
return 0
fi
fi
done
rm -rf "$tmp"
return 1
}
# ── Holen oder aktualisieren ─────────────────────────────────────────────────
kopf "Repo"
if [ -d "$ZIEL/.git" ]; then
ok "Arbeitskopie vorhanden — aktualisiere"
if git -C "$ZIEL" pull --ff-only; then
ok "aktuell"
else
warn "git pull fehlgeschlagen."
hinweis "Lokale Änderungen? Dann: cd ~/hpos && git stash && git pull"
exit 1
fi
else
# --depth reicht nicht: für 'git pull' später brauchen wir eine vollwertige
# Arbeitskopie, kein abgeschnittenes Archiv.
if git clone "$REPO" "$ZIEL"; then
ok "geklont nach $ZIEL"
else
fehl "git clone fehlgeschlagen."
hinweis "Adresse war: $REPO"
echo
# Ein scheiternder Klon bei erreichbarem Repo hat fast immer eine
# serverseitige Ursache: upload-pack stirbt beim Schnüren des Pakets,
# während die Objekte selbst heil sind. Erkennbar daran, dass sich ein
# Archiv weiterhin erzeugen lässt — und genau das ist die Rückfallebene.
if archiv_holen; then
warn "Über ein Archiv geholt, NICHT als Arbeitskopie."
hinweis "'git pull' funktioniert damit nicht. Sobald der Server wieder"
hinweis "Pakete ausliefert: rm -rf ~/hpos && bash /sdcard/hpos-init.sh"
else
fehl "Auch die Rückfallebene über das Archiv hat nicht geklappt."
hinweis "Ist das Repo öffentlich lesbar? Ohne das braucht es Zugangsdaten,"
hinweis "und die gehören nicht aufs Telefon."
exit 1
fi
fi
fi
chmod +x "$ZIEL"/spike/*.sh "$ZIEL"/spike/inner/*.sh 2>/dev/null || true
# ── Weiter ───────────────────────────────────────────────────────────────────
kopf "Fertig"
cat <<TEXT
Das Repo liegt jetzt unter ~/hpos und ist eine Arbeitskopie.
Aktualisieren später:
cd ~/hpos && git pull
Nächster Schritt:
cd ~/hpos
bash spike/00-bootstrap-termux.sh
Danach die Beweise der Reihe nach — S1 zuerst, weil er der wackligste ist:
bash spike/01-s1-plasma-mobile.sh
bash spike/02-s2-mikrofon.sh
bash spike/03-s3-pipewire-kamera.sh
bash spike/04-s4-intent-handoff.sh
TEXT