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>
166 lines
6.3 KiB
Bash
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
|
|
}
|