Files
linux-on-android-without-root/provision/provision.sh
T
StefanandClaude Opus 5 d334219c4f Provisioning ohne Kabel: ADB über WLAN
provision.sh fragt beim Start nach USB oder WLAN, statt ohne Gerät einfach
abzubrechen. Der WLAN-Weg braucht kein Kabel — Android 11 und neuer koppeln
per sechsstelligem Code.

adb-wireless.sh sucht Kopplungs- und Verbindungsdienst per mDNS, statt die
Adressen abtippen zu lassen. Beide Ports vergibt Android bei jedem Einschalten
neu, und sie sind verschieden — das ist die häufigste Verwechslung dabei.
Fällt auf manuelle Eingabe zurück, wenn das Netz Multicast blockiert.

provision.sh kann die Skripte anschließend per adb push aufs Telefon legen.
Das erspart es, Zugangsdaten für ein privates Repo auf einer Bildschirmtastatur
einzutippen. Mit dem Hinweis, dass /sdcard keine Ausführungsrechte kennt und
die Dateien deshalb erst nach ~ kopiert werden müssen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 17:43:31 +02:00

244 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
# HPOS — Ersteinrichtung vom PC aus, per ADB.
#
# ADB wird ausschließlich hier gebraucht, einmalig. Im Dauerbetrieb kommt das
# System mit gewöhnlichen App-Berechtigungen aus — das ist eine harte Regel des
# Projekts, siehe CONTRIBUTING.md.
#
# Voraussetzung: Entwickleroptionen aktiv. Die Verbindung geht per USB-Kabel ODER
# per WLAN (Android 11 und neuer) — das Skript fragt danach, wenn kein Gerät da ist.
#
# Aufruf: ./provision/provision.sh [--dry-run]
set -uo pipefail
TERMUX=com.termux
TROCKEN=0
[ "${1:-}" = "--dry-run" ] && TROCKEN=1
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"; }
# Führt ein adb-Kommando aus und meldet das Ergebnis, ohne bei Fehlschlag
# abzubrechen: Hersteller-ROMs kennen nicht jedes appops-Ziel, und ein fehlendes
# ist kein Grund, die restliche Einrichtung liegen zu lassen.
adbs() {
local beschreibung="$1"; shift
if [ "$TROCKEN" = 1 ]; then
printf '%s ? %s%s (adb shell %s)\n' "$C_DIM" "$beschreibung" "$C_OFF" "$*"
return 0
fi
local aus
if aus=$(adb shell "$@" 2>&1); then
if printf '%s' "$aus" | grep -qiE 'error|exception|denied|unknown'; then
warn "$beschreibung — ROM hat abgelehnt"
hinweis "$(printf '%s' "$aus" | head -1)"
return 1
fi
ok "$beschreibung"
return 0
fi
warn "$beschreibung — fehlgeschlagen"
hinweis "$(printf '%s' "$aus" | head -1)"
return 1
}
# ── Gerät ────────────────────────────────────────────────────────────────────
kopf "Gerät"
command -v adb >/dev/null 2>&1 || { fehl "adb nicht gefunden. Bitte android-tools-adb installieren."; exit 1; }
HIER="$(cd "$(dirname "$0")" && pwd)"
ANZAHL=$(adb devices | grep -cw 'device$' || true)
# Ohne Gerät nicht einfach abbrechen: der häufigste Fall ist, dass gar kein Kabel
# zur Hand ist. Android 11+ kann Wireless Debugging, das reicht für alles hier.
if [ "$ANZAHL" -eq 0 ]; then
warn "Kein Gerät verbunden."
if [ ! -t 0 ]; then
hinweis "Keine Eingabe möglich — bitte erst ./provision/adb-wireless.sh ausführen."
exit 1
fi
cat <<'TEXT'
Wie soll verbunden werden?
[u] USB-Kabel
Entwickleroptionen und USB-Debugging aktiv, Dialog "Diesem Computer
vertrauen" auf dem Telefon bestätigt.
[w] WLAN, ohne Kabel (Android 11 und neuer)
Einmalige Kopplung per sechsstelligem Code. Danach läuft alles
über das Netz — ein Kabel wird nie gebraucht.
[a] Abbrechen
TEXT
printf '\n Auswahl > '
read -r WAHL </dev/tty
case "$WAHL" in
w|W)
if [ ! -x "$HIER/adb-wireless.sh" ]; then
fehl "adb-wireless.sh nicht gefunden neben diesem Skript."
exit 1
fi
"$HIER/adb-wireless.sh" || exit 1
ANZAHL=$(adb devices | grep -cw 'device$' || true)
;;
u|U)
printf ' Kabel anschließen und Enter drücken > '
read -r _ </dev/tty
adb wait-for-device &
WARTE=$!
# Nicht ewig hängen bleiben, falls das Kabel nur lädt und keine Daten überträgt.
( sleep 60; kill "$WARTE" 2>/dev/null ) >/dev/null 2>&1 &
wait "$WARTE" 2>/dev/null
ANZAHL=$(adb devices | grep -cw 'device$' || true)
;;
*)
hinweis "Abgebrochen."
exit 0
;;
esac
if [ "$ANZAHL" -eq 0 ]; then
fehl "Es ist weiterhin kein Gerät verbunden."
adb devices | sed 's/^/ /'
hinweis "Steht dort 'unauthorized', den Dialog auf dem Telefon bestätigen."
exit 1
fi
ok "Gerät verbunden"
elif [ "$ANZAHL" -gt 1 ]; then
fehl "Mehrere Geräte verbunden — bitte nur eines aktiv lassen."
adb devices | sed 's/^/ /'
hinweis "Überzählige trennen, per WLAN verbundene mit: adb disconnect <ip:port>"
exit 1
fi
for p in ro.product.manufacturer ro.product.model ro.product.device \
ro.build.version.release ro.board.platform; do
printf ' %-28s %s\n' "$p" "$(adb shell getprop "$p" 2>/dev/null | tr -d '\r')"
done
[ "$TROCKEN" = 1 ] && warn "Trockenlauf — es wird nichts verändert."
# ── Termux vorhanden? ────────────────────────────────────────────────────────
kopf "Termux"
if adb shell pm list packages 2>/dev/null | tr -d '\r' | grep -q "^package:$TERMUX$"; then
ok "$TERMUX ist installiert"
else
fehl "$TERMUX ist nicht installiert."
hinweis "Termux von F-Droid oder GitHub installieren, dann dieses Skript erneut laufen lassen."
hinweis "Nicht aus dem Play Store — die dortige Fassung ist veraltet und unbrauchbar."
exit 1
fi
# ── Hintergrundbetrieb, Android-Standardebene ────────────────────────────────
# Der Punkt, an dem das Konzept in der Praxis scheitern kann. Diese Maßnahmen
# überleben Neustarts. Die Entwickleroptionen helfen hier NICHT — sie betreffen
# nur gecachte Prozesse, nicht Vordergrunddienste.
kopf "Hintergrundbetrieb (Android-Standardebene)"
adbs "Aus der Doze-Beschränkung ausgenommen" dumpsys deviceidle whitelist "+$TERMUX"
adbs "RUN_IN_BACKGROUND erlaubt" cmd appops set "$TERMUX" RUN_IN_BACKGROUND allow
adbs "RUN_ANY_IN_BACKGROUND erlaubt" cmd appops set "$TERMUX" RUN_ANY_IN_BACKGROUND allow
adbs "Standby-Bucket auf 'never' gesetzt" am set-standby-bucket "$TERMUX" never
adbs "Adaptive Akkunutzung abgeschaltet" settings put global adaptive_battery_management_enabled 0
adbs "Akku-Optimierung ignoriert" cmd appops set "$TERMUX" REQUEST_IGNORE_BATTERY_OPTIMIZATIONS allow
# Die Zusatz-APKs, sofern schon installiert. Fehlen sie, ist das hier kein Problem.
for extra in com.termux.api com.termux.x11 com.termux.boot; do
if adb shell pm list packages 2>/dev/null | tr -d '\r' | grep -q "^package:$extra$"; then
adbs " $extra aus der Doze-Beschränkung" dumpsys deviceidle whitelist "+$extra"
adbs " $extra darf im Hintergrund laufen" cmd appops set "$extra" RUN_ANY_IN_BACKGROUND allow
fi
done
# ── Berechtigungen ───────────────────────────────────────────────────────────
kopf "Berechtigungen"
for perm in \
android.permission.RECORD_AUDIO \
android.permission.CAMERA \
android.permission.ACCESS_FINE_LOCATION \
android.permission.READ_EXTERNAL_STORAGE \
android.permission.WRITE_EXTERNAL_STORAGE
do
adbs "$(basename "${perm//./\/}") für Termux:API" pm grant com.termux.api "$perm" 2>/dev/null || true
done
hinweis "Fehlschläge sind normal, solange Termux:API noch nicht installiert ist."
# ── Was ADB nicht kann ───────────────────────────────────────────────────────
kopf "Von Hand zu erledigen"
HERSTELLER=$(adb shell getprop ro.product.manufacturer 2>/dev/null | tr -d '\r')
cat <<TEXT
Die folgenden Punkte liegen unterhalb der Android-Mechanismen und sind per
ADB nicht zuverlässig erreichbar. Ohne sie beendet das ROM den Stack über Nacht.
1. Einstellungen → Apps → Termux → Akku → "Nicht optimieren"
2. Einstellungen → Akku → "Sleep Standby Optimization" ausschalten
3. Einstellungen → Akku → adaptive Akkunutzung ausschalten
4. Termux im Task-Manager anpinnen (Schloss-Symbol)
5. Für Overlay-Begleit-Apps: "Über anderen Apps anzeigen" erlauben
TEXT
case "$HERSTELLER" in
[Oo]ne[Pp]lus|OPPO|oppo|realme)
printf '\n%s Zu deinem Gerät:%s\n' "$C_WARN" "$C_OFF"
hinweis "OxygenOS/ColorOS friert Apps besonders aggressiv ein."
hinweis "Zusätzlich unter Einstellungen → Akku → Akkuoptimierung die"
hinweis "erweiterte bzw. 'intelligente' Optimierung für Termux abschalten."
;;
[Xx]iaomi|[Rr]edmi|[Pp]oco|samsung|Samsung)
printf '\n%s Zu deinem Gerät:%s\n' "$C_WARN" "$C_OFF"
hinweis "Dieser Hersteller ist für aggressives Beenden bekannt."
hinweis "Zusätzlich Autostart erlauben und die App von der Speicherbereinigung ausnehmen."
;;
esac
# ── Repo aufs Telefon ────────────────────────────────────────────────────────
# adb push funktioniert auch über WLAN. Das erspart es, auf dem Telefon Zugangsdaten
# für ein privates Repo eintippen zu müssen — auf einer Bildschirmtastatur eine Qual.
kopf "Skripte aufs Telefon"
REPO_ROOT="$(cd "$HIER/.." && pwd)"
ZIEL=/sdcard/hpos
if [ "$TROCKEN" = 1 ]; then
warn "Trockenlauf — es wird nichts übertragen."
else
printf ' Die Spike-Skripte jetzt nach %s übertragen? [J/n] > ' "$ZIEL"
read -r UEBERTRAGEN </dev/tty || UEBERTRAGEN=n
case "${UEBERTRAGEN:-j}" in
j|J|"")
adb shell rm -rf "$ZIEL" >/dev/null 2>&1
if adb push "$REPO_ROOT" "$ZIEL" >/dev/null 2>&1; then
ok "Übertragen nach $ZIEL"
hinweis "In Termux nach ~ kopieren, damit die Dateien ausführbar sein können:"
hinweis " cp -r /sdcard/hpos ~/hpos && cd ~/hpos"
hinweis "(auf /sdcard gibt es keine Ausführungsrechte — das ist normal)"
else
warn "Übertragung fehlgeschlagen — dann per git clone auf dem Telefon."
fi
;;
*) hinweis "Übersprungen." ;;
esac
fi
kopf "Fertig"
cat <<TEXT
Nächste Schritte auf dem Telefon, in Termux:
cp -r /sdcard/hpos ~/hpos && cd ~/hpos # falls oben übertragen
# oder: pkg install -y git && git clone <repo-url> hpos && cd hpos
bash spike/00-bootstrap-termux.sh
Danach die Beweise der Reihe nach — S1 zuerst, weil er der wackligste ist.
Ergebnisse gehören nach docs/spike-protokoll.md.
Nicht vergessen: die oben genannten Handgriffe von Hand erledigen.
Ohne sie beendet das ROM den Stack über Nacht.
TEXT