Files
linux-on-android-without-root/provision/lib.sh
T
StefanandClaude Opus 5 915fe53eeb Mehrere Geräte gleichzeitig unterstützen
Ein bereits verbundenes Gerät war bisher ein Grund auszusteigen, und provision.sh
brach bei mehr als einem sogar ab. Beim Gerätewechsel ist genau das aber der
Normalfall: altes und neues Telefon müssen zusammen erreichbar sein, sonst lässt
sich nichts klonen.

adb-wireless.sh zeigt jetzt die verbundenen Geräte mit Hersteller und Modell und
bietet an, weiterzugehen, ein weiteres Gerät aufzunehmen oder eines zu trennen.
provision.sh fragt bei mehreren, welches eingerichtet werden soll.

Die Auswahl landet in ADB_SERIAL, und die adb-Hülle in lib.sh ergänzt -s
selbsttätig — aber nur bei Unterbefehlen, die sich an ein Gerät richten.
'adb -s X devices' oder 'adb -s X connect' wären Unsinn und würden fehlschlagen.

Dazu eine Korrektur, die beim Hinzufügen sonst falsch angeschlagen hätte: nach
dem Koppeln reicht 'irgendein Gerät verbunden' als Erfolgsnachweis nicht, denn
das erste Telefon ist ja noch da. Gezählt wird jetzt, ob eines DAZUGEKOMMEN ist.

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

166 lines
6.3 KiB
Bash

#!/usr/bin/env bash
# Gemeinsame Hilfsfunktionen für die Provisioning-Skripte.
# Wird eingebunden, nicht direkt ausgeführt.
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"; }
# ── Das richtige adb finden ──────────────────────────────────────────────────
# Debians Paket android-tools-adb liefert Version 29. 'adb pair' — und damit die
# Kopplung über WLAN — kam erst mit platform-tools 30. Wer beides installiert hat,
# bekommt je nach PATH-Reihenfolge mal das eine und mal das andere. Deshalb wird
# hier gezielt eine Fassung gesucht, die 'pair' beherrscht, statt sich auf PATH
# zu verlassen.
#
# Setzt ADB_BIN und definiert eine Shell-Funktion 'adb', die darauf zeigt —
# so müssen die Aufrufstellen nichts wissen.
# Bewusst ohne Pipe: 'adb pair' ohne Argumente beendet sich mit Code 1, weil es ein
# Aufruffehler ist. Unter 'set -o pipefail' würde das die ganze Pipeline als
# fehlgeschlagen gelten lassen — obwohl grep den Hilfetext gefunden hat.
adb_kann_pair() {
local aus
aus="$("$1" pair 2>&1 || true)"
case "$aus" in *"usage: adb pair"*) return 0 ;; esac
return 1
}
adb_version() { "$1" version 2>/dev/null | sed -n '2p' | sed 's/^Version //'; }
adb_finden() {
local kandidaten=() k
# Eine ausdrücklich gesetzte Vorgabe gilt absolut — auch wenn sie kein 'pair'
# kann. Wer ADB= setzt, meint es so; stillschweigend etwas anderes zu nehmen
# wäre die unangenehmere Überraschung.
if [ -n "${ADB:-}" ]; then
if [ ! -x "$ADB" ]; then
fehl "ADB=$ADB ist nicht ausführbar."
return 1
fi
ADB_BIN="$ADB"
adb_kann_pair "$ADB_BIN" && return 0 || return 2
fi
kandidaten+=(
"$HOME/Android/Sdk/platform-tools/adb"
"$HOME/Library/Android/sdk/platform-tools/adb"
"${ANDROID_HOME:-/nonexistent}/platform-tools/adb"
"${ANDROID_SDK_ROOT:-/nonexistent}/platform-tools/adb"
)
# Alles, was in PATH steht, ebenfalls prüfen — in PATH-Reihenfolge.
while IFS= read -r k; do kandidaten+=("$k"); done < <(type -pa adb 2>/dev/null)
local erstes_gefundenes=""
for k in "${kandidaten[@]}"; do
[ -x "$k" ] || continue
[ -n "$erstes_gefundenes" ] || erstes_gefundenes="$k"
if adb_kann_pair "$k"; then
ADB_BIN="$k"
return 0
fi
done
# Keines kann pair. Das ältere trotzdem melden — für USB reicht es.
if [ -n "$erstes_gefundenes" ]; then
ADB_BIN="$erstes_gefundenes"
return 2
fi
return 1
}
# Muss von jedem Skript einmal aufgerufen werden, bevor adb benutzt wird.
adb_einrichten() {
local rc
adb_finden; rc=$?
case $rc in
0) : ;;
2)
warn "Gefundenes adb ist zu alt für die WLAN-Kopplung: $(adb_version "$ADB_BIN")"
hinweis "$ADB_BIN"
hinweis "'adb pair' gibt es erst ab platform-tools 30. Debians Paket"
hinweis "android-tools-adb hängt auf Version 29 — damit geht nur USB."
hinweis "Aktuelle Fassung: developer.android.com/tools/releases/platform-tools"
;;
*)
fehl "Kein adb gefunden."
hinweis "Entweder android-tools-adb installieren (nur USB) oder die"
hinweis "platform-tools von Google entpacken (USB und WLAN)."
exit 1
;;
esac
# Ab hier zeigt 'adb' immer auf die ausgewählte Fassung, unabhängig von PATH.
#
# Ist ein Gerät ausgewählt (ADB_SERIAL), wird -s ergänzt — aber nur bei
# Unterbefehlen, die sich an ein bestimmtes Gerät richten. 'adb -s X connect'
# oder 'adb -s X devices' wären Unsinn und würden fehlschlagen.
adb() {
case "${1:-}" in
shell|push|pull|install|install-multiple|uninstall|forward|reverse| \
logcat|sync|reboot|remount|root|unroot|bugreport|wait-for-device)
if [ -n "${ADB_SERIAL:-}" ]; then
"$ADB_BIN" -s "$ADB_SERIAL" "$@"
return
fi
;;
esac
"$ADB_BIN" "$@"
}
return $rc
}
# ── Geräteauswahl ────────────────────────────────────────────────────────────
# Mehrere Geräte gleichzeitig sind der Normalfall, sobald man ein zweites Telefon
# koppelt oder nebenher noch eines am Kabel hängt. Statt abzubrechen wird gefragt.
ADB_SERIAL="${ADB_SERIAL:-}"
adb_geraete() { adb devices | awk '$2 == "device" { print $1 }'; }
geraet_beschreiben() {
local serial="$1" hersteller modell
hersteller=$("$ADB_BIN" -s "$serial" shell getprop ro.product.manufacturer 2>/dev/null | tr -d '\r')
modell=$("$ADB_BIN" -s "$serial" shell getprop ro.product.model 2>/dev/null | tr -d '\r')
printf '%s %s' "${hersteller:-?}" "${modell:-?}"
}
# Wählt ein Gerät aus und setzt ADB_SERIAL.
# 0 = ein Gerät ausgewählt
# 1 = gar kein Gerät verbunden
geraet_waehlen() {
local liste=() zeile i wahl
while IFS= read -r zeile; do
[ -n "$zeile" ] && liste+=("$zeile")
done < <(adb_geraete)
case ${#liste[@]} in
0) ADB_SERIAL=""; return 1 ;;
1) ADB_SERIAL="${liste[0]}"; return 0 ;;
esac
kopf "Mehrere Geräte verbunden"
for i in "${!liste[@]}"; do
printf ' [%d] %-24s %s\n' "$((i + 1))" "${liste[i]}" "$(geraet_beschreiben "${liste[i]}")"
done
printf '\n Welches Gerät soll eingerichtet werden? [1] > '
read -r wahl </dev/tty || wahl=1
wahl="${wahl:-1}"
if [ "$wahl" -ge 1 ] 2>/dev/null && [ "$wahl" -le ${#liste[@]} ]; then
ADB_SERIAL="${liste[$((wahl - 1))]}"
ok "Gewählt: $ADB_SERIAL ($(geraet_beschreiben "$ADB_SERIAL"))"
return 0
fi
warn "Ungültige Auswahl — nehme das erste Gerät."
ADB_SERIAL="${liste[0]}"
return 0
}