Files
linux-on-android-without-root/spike/lib.sh
T
StefanandClaude Opus 5 2d3c2fbc6d Vorabprüfung: proot-distro und Rootfs vor jedem Beweis
Aus dem Gerätelauf: S2 lief bis Stufe 1 durch und scheiterte dann an
'proot-distro: cannot execute: required file not found'. Danach meldete die
Auswertung folgerichtig 'S2 gescheitert' — was den Beweis inhaltlich belastet,
obwohl nur die Grundlage fehlte. Genau diese Verwechslung soll der Spike nicht
produzieren.

Alle Beweise prüfen jetzt vorab, ob proot-distro ausführbar ist und das Rootfs
steht, und brechen sonst mit klarer Ansage ab statt mitten im Test aufzulaufen.

Die Meldung selbst ist irreführend: 'required file not found' heißt nicht, dass
proot-distro fehlt — bash hat es gefunden und nennt den vollen Pfad. Es fehlt der
Interpreter aus dessen Shebang-Zeile. Die Prüfung sagt das ausdrücklich und nennt
Datei und Shebang, statt den Suchenden an der falschen Stelle graben zu lassen.
00-bootstrap versucht in dem Fall selbsttätig eine Neuinstallation.

Dazu die Berechtigungsprüfung entschärft: dumpsys verlangt die DUMP-Berechtigung,
die eine gewöhnliche App nicht hat. Das Fehlschlagen ist erwartbar und kein
Warnsignal; die Meldung nennt jetzt den Weg über adb statt Ratlosigkeit zu säen.

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

153 lines
5.2 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"
if proot-distro list --installed 2>/dev/null | grep -q "^$distro\b" \
|| [ -d "$PREFIX/var/lib/proot-distro/installed-rootfs/$distro" ]; then
ok "$distro-Rootfs vorhanden"
else
fail "$distro-Rootfs fehlt"
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
}