Files
linux-on-android-without-root/spike/lib.sh
T
StefanandClaude Opus 5 f20ad44e25 Rootfs am Anmeldeversuch erkennen, nicht an Pfaden
Der zweite Bootstrap-Lauf brach ab, obwohl beim ersten alles stand: proot-distro
hat sein Ablageformat gewechselt — sichtbar an 'Migrating legacy container' —
und danach lag das Rootfs nicht mehr dort, wo meine Prüfung nachsah. Sie meldete
'nicht installiert', die folgende Installation scheiterte an 'already installed',
und der Lauf brach ab. Ein Fehler in der Erkennung, nicht auf dem Gerät.

Geprüft wird jetzt mit 'proot-distro login <distro> -- true'. Das fragt nicht, wo
etwas liegt oder wie eine Ausgabe formatiert ist, sondern ob es funktioniert —
und überlebt damit auch den nächsten Formatwechsel.

Zusätzlich gilt 'already installed' nicht mehr als Fehler: entscheidend ist
allein, ob die Anmeldung danach klappt. Tut sie es nicht, nennt das Skript die
Handgriffe zum Neuaufsetzen, statt nur abzubrechen.

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

155 lines
5.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Gemeinsame Hilfsfunktionen für die Phase-0-Spike-Skripte.
# Wird von den 0x-Skripten eingebunden, nicht direkt ausgeführt.
# Farben nur wenn wir auf einem Terminal landen — sonst verschmutzen sie das Protokoll.
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
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUT_DIR="$REPO_ROOT/spike/out"
mkdir -p "$OUT_DIR"
# Jeder Lauf bekommt sein eigenes Protokoll. Die Sammlung ist später die halbe
# Auswertung — deshalb wird alles mitgeschrieben, auch was funktioniert hat.
LOG="${LOG:-$OUT_DIR/$(basename "${0%.sh}").log}"
log() { printf '%s\n' "$*" | tee -a "$LOG"; }
section() { log ""; log "${C_HEAD}══ $* ══${C_OFF}"; }
ok() { log "${C_OK}${C_OFF} $*"; }
warn() { log "${C_WARN} !${C_OFF} $*"; }
fail() { log "${C_ERR}${C_OFF} $*"; }
hint() { log "${C_DIM} $*${C_OFF}"; }
# Befehl ausführen, Ausgabe ins Protokoll, Fehler nicht tödlich.
# Für alles, was scheitern DARF, ohne den Spike abzubrechen.
try() {
log "${C_DIM} \$ $*${C_OFF}"
if "$@" >>"$LOG" 2>&1; then
return 0
else
local rc=$?
warn "fehlgeschlagen (Code $rc): $*"
return $rc
fi
}
# Wie try(), aber ein Fehlschlag beendet den Spike. Für echte Voraussetzungen.
need() {
log "${C_DIM} \$ $*${C_OFF}"
if ! "$@" >>"$LOG" 2>&1; then
fail "Abbruch — notwendiger Schritt fehlgeschlagen: $*"
log ""
log "Vollständiges Protokoll: $LOG"
exit 1
fi
}
have() { command -v "$1" >/dev/null 2>&1; }
in_termux() {
case "${PREFIX:-}" in
*com.termux*) [ -d "$PREFIX/bin" ] ;;
*) return 1 ;;
esac
}
require_termux() {
if ! in_termux; then
fail "Dieses Skript läuft in Termux auf dem Telefon, nicht auf dem PC."
exit 1
fi
}
# Prüft, ob die Grundlage steht, BEVOR ein Beweis losläuft. Ohne das scheitert ein
# Test mitten im Ablauf und sieht aus wie ein inhaltlicher Fehlschlag, obwohl nur
# die Vorbereitung fehlt — die irreführendste Sorte Fehler.
voraussetzungen_pruefen() {
local distro="${1:-debian}" fehlt=0
section "Voraussetzungen"
if ! have proot-distro; then
fail "proot-distro ist nicht installiert"
hint "Nachholen mit: bash spike/00-bootstrap-termux.sh"
return 1
fi
# 'cannot execute: required file not found' heißt NICHT, dass das Skript fehlt.
# Es heißt, dass der Interpreter aus seiner Shebang-Zeile fehlt. Der Unterschied
# kostet sonst eine halbe Stunde Suche an der falschen Stelle.
local pfad interpreter
pfad="$(command -v proot-distro)"
if ! proot-distro list >/dev/null 2>&1; then
fail "proot-distro lässt sich nicht ausführen"
interpreter="$(head -1 "$pfad" 2>/dev/null | sed 's|^#!||; s| .*||')"
log " Datei: $pfad"
log " Shebang: ${interpreter:-keine}"
if [ -n "$interpreter" ] && [ ! -x "$interpreter" ]; then
fail "Der Interpreter $interpreter fehlt oder ist nicht ausführbar."
hint "Das ist die Ursache, nicht proot-distro selbst."
hint "Reparieren mit: pkg install -y bash coreutils proot proot-distro"
else
hint "Reparieren mit: pkg reinstall -y proot-distro"
fi
return 1
fi
ok "proot-distro ausführbar"
# Anmeldeversuch statt Pfad- oder Ausgabeprüfung: proot-distro hat sein
# Ablageformat gewechselt, und danach lag das Rootfs woanders als erwartet.
# Diese Prüfung fragt nicht, wo etwas liegt, sondern ob es funktioniert.
if proot-distro login "$distro" -- true >/dev/null 2>&1; then
ok "$distro-Rootfs lauffähig"
else
fail "$distro-Rootfs fehlt oder startet nicht"
hint "Nachholen mit: bash spike/00-bootstrap-termux.sh"
fehlt=1
fi
return $fehlt
}
# Fragt am Ende jedes Beweises nach dem, was nur ein Mensch beurteilen kann:
# ob es tatsächlich funktioniert hat. Das Ergebnis geht ins Protokoll.
verdict() {
local beweis="$1" frage="$2"
log ""
log "${C_HEAD}── Beurteilung $beweis ──${C_OFF}"
log "$frage"
printf ' [j] ja [n] nein [t] teilweise > '
read -r antwort </dev/tty || antwort="?"
local text
case "$antwort" in
j|J) text="BESTANDEN" ;;
n|N) text="GESCHEITERT" ;;
t|T) text="TEILWEISE" ;;
*) text="UNKLAR" ;;
esac
printf ' Anmerkung (eine Zeile, Enter für nichts) > '
read -r notiz </dev/tty || notiz=""
log " Ergebnis $beweis: $text ${notiz:+— $notiz}"
printf '%s\t%s\t%s\n' "$beweis" "$text" "$notiz" >>"$OUT_DIR/ergebnisse.tsv"
log ""
log "Ins Protokoll übertragen: docs/spike-protokoll.md"
log "Rohdaten: $LOG"
}
# Gerätesteckbrief — landet in jedem Protokoll, damit Meldungen vergleichbar sind.
geraete_steckbrief() {
section "Gerät"
local p
for p in ro.product.manufacturer ro.product.model ro.product.device \
ro.build.version.release ro.build.version.sdk ro.board.platform \
ro.hardware ro.soc.model; do
log " $p = $(getprop "$p" 2>/dev/null || echo '?')"
done
log " Arch = $(uname -m)"
log " Kernel = $(uname -r)"
if have free; then log " RAM = $(free -h 2>/dev/null | awk '/Mem:/{print $2}')"; fi
}