adb gezielt auswählen statt der PATH-Reihenfolge zu vertrauen

Debians Paket android-tools-adb liefert Version 29 und kennt kein 'adb pair' —
das kam erst mit platform-tools 30. Wer beides installiert hat, bekommt je nach
PATH-Reihenfolge und Alter der Terminalsitzung mal das eine und mal das andere,
und die WLAN-Kopplung scheitert scheinbar grundlos.

provision/lib.sh sucht deshalb gezielt eine Fassung, die 'pair' beherrscht, und
schiebt eine Shell-Funktion 'adb' davor, sodass die Aufrufstellen unverändert
bleiben. Eine ausdrücklich gesetzte Vorgabe ADB= gilt absolut, auch wenn sie
kein pair kann — stillschweigend etwas anderes zu nehmen wäre die unangenehmere
Überraschung. Fehlt pair, läuft provision.sh mit einer Warnung weiter (für USB
reicht es), adb-wireless.sh bricht sauber ab.

Die Prüfung kommt bewusst ohne Pipe aus: 'adb pair' ohne Argumente endet mit
Code 1, weil es ein Aufruffehler ist. Unter 'set -o pipefail' hätte das die
gesamte Pipeline als fehlgeschlagen gelten lassen, obwohl grep den Hilfetext
gefunden hatte — die Erkennung meldete dadurch selbst adb 36 als zu alt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan
2026-08-09 17:53:41 +02:00
co-authored by Claude Opus 5
parent d334219c4f
commit 410cf01973
3 changed files with 121 additions and 29 deletions
+8 -17
View File
@@ -11,24 +11,15 @@
# Aufruf: ./provision/adb-wireless.sh # Aufruf: ./provision/adb-wireless.sh
set -uo pipefail set -uo pipefail
if [ -t 1 ]; then source "$(dirname "$0")/lib.sh"
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' kopf "Werkzeug"
if adb_einrichten; then
ok "adb $(adb_version "$ADB_BIN") — kann WLAN-Kopplung"
hinweis "$ADB_BIN"
else else
C_OK=""; C_WARN=""; C_ERR=""; C_HEAD=""; C_DIM=""; C_OFF="" fehl "Ohne 'adb pair' ist eine Kopplung über WLAN nicht möglich."
fi hinweis "Entweder aktuelle platform-tools installieren, oder doch ein Kabel besorgen."
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"; }
command -v adb >/dev/null 2>&1 || { fehl "adb nicht gefunden."; exit 1; }
# Ab Version 30 gibt es 'adb pair'. Ältere Fassungen können Wireless Debugging nicht.
if ! adb pair 2>&1 | grep -q 'usage: adb pair'; then
fehl "Dieses adb kennt 'adb pair' nicht — zu alt für Wireless Debugging."
hinweis "Aktuelle platform-tools von developer.android.com/tools/releases/platform-tools"
exit 1 exit 1
fi fi
adb start-server >/dev/null 2>&1 adb start-server >/dev/null 2>&1
+104
View File
@@ -0,0 +1,104 @@
#!/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.
adb() { "$ADB_BIN" "$@"; }
return $rc
}
+9 -12
View File
@@ -15,17 +15,13 @@ TERMUX=com.termux
TROCKEN=0 TROCKEN=0
[ "${1:-}" = "--dry-run" ] && TROCKEN=1 [ "${1:-}" = "--dry-run" ] && TROCKEN=1
if [ -t 1 ]; then source "$(dirname "$0")/lib.sh"
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' # Wählt eine adb-Fassung aus, statt sich auf die Reihenfolge in PATH zu verlassen:
else # Debians Paket ist Version 29 und kennt kein 'adb pair'. Rückgabewert 2 heißt
C_OK=""; C_WARN=""; C_ERR=""; C_HEAD=""; C_DIM=""; C_OFF="" # "gefunden, aber zu alt für WLAN" — für USB reicht es trotzdem.
fi ADB_KANN_WLAN=1
kopf() { printf '\n%s══ %s ══%s\n' "$C_HEAD" "$*" "$C_OFF"; } adb_einrichten || ADB_KANN_WLAN=0
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 # Führt ein adb-Kommando aus und meldet das Ergebnis, ohne bei Fehlschlag
# abzubrechen: Hersteller-ROMs kennen nicht jedes appops-Ziel, und ein fehlendes # abzubrechen: Hersteller-ROMs kennen nicht jedes appops-Ziel, und ein fehlendes
@@ -53,7 +49,7 @@ adbs() {
# ── Gerät ──────────────────────────────────────────────────────────────────── # ── Gerät ────────────────────────────────────────────────────────────────────
kopf "Gerät" kopf "Gerät"
command -v adb >/dev/null 2>&1 || { fehl "adb nicht gefunden. Bitte android-tools-adb installieren."; exit 1; } hinweis "adb $(adb_version "$ADB_BIN")$ADB_BIN"
HIER="$(cd "$(dirname "$0")" && pwd)" HIER="$(cd "$(dirname "$0")" && pwd)"
@@ -81,6 +77,7 @@ if [ "$ANZAHL" -eq 0 ]; then
[a] Abbrechen [a] Abbrechen
TEXT TEXT
[ "$ADB_KANN_WLAN" = 0 ] && warn "Achtung: das gefundene adb kann kein WLAN — [w] wird scheitern."
printf '\n Auswahl > ' printf '\n Auswahl > '
read -r WAHL </dev/tty read -r WAHL </dev/tty
case "$WAHL" in case "$WAHL" in