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>
198 lines
8.7 KiB
Bash
Executable File
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
|