HowTo: Der adb-Manager ist da


#1

Hi.
Da ich ein großer Fan des Tools “dialog” bin, habe ich etwas gebastelt. Herausgekommen ist dabei der “adb-manager.sh” (im Moment Version 1.1). Das ist ein Scipt, das zusammen mit Raccoon ganz gute Dienste leisten kann, sofern man mehrere/viele Android-Geräte mit adb verwalten will/muss/kann.

Ich habe das ganze bei mir so angelegt, dass ich mir zunächst Raccoon heruntergeladen und eingerichtet habe. Danach habe ich das Verzeichnis “backup” zusätzlich in dem Raccoon-Verzeichnis erzeugt und dazu das unten aufgeführte Script im Raccoon-Verzeichnis ausführbar gemacht. Wenn man mehr als ein Gerät angeschlossen hat, kann man das nun relativ bequem damit verwalten!

Über Rückmeldungen würde ich mich natürlich freuen. Und keine Sorge: Das Script ist noch nicht scharf geschaltet. Es werden alle Befehle nur als “echo” ausgespuckt ohne sie wirklich auszuführen! Ihr könnt also alles bedenkenlos testen, ohne Eure Geräte zu verändern. Ich hatte hier nur zwei Smartphones per USB-Kabel zur Verfügung mit denen die Tests alle geklappt haben. Auf allen Android-Geräten muss der USB-Debugging-Mode aktiviert sein, damit der Zugriff funktioniert. Meines Wissens müssen die Geräte aber nicht zwingend gerooted sein (was beide Geräte hier jedoch waren)…

Wer das Script gebrauchen kann --> Hier kommt es! (GPLv3) :slight_smile:

#!/bin/bash
#set -x

#########################################################################################################
# Scriptname :    adb-manager.sh 
# Licence    :    GPLv3
# Author     :    Vorlage von Bernd Holzhauer; geändert und angepasst von M. Hagedorn
# WebSite    :    https://www.cc-c.de/german/linux/linux-dialog.php
# Date       :    2018-07-05
# Requires   :    dialog, adb, adb-tools, USB-Debugging auf Android-Geräten aktiviert
# Category   :    geeignet für Linux zur Verwaltung von Android-Geräten mittels "adb"
# Category   :    Initiative fuer http://www.linuxmuster.net (Verwaltung von Geräten mit adb)
#Version     :
VER='1.1'
#########################################################################################################

# Anleitung : Das Script arbeitet z.B. zusammen mit Raccoon (https://raccoon.onyxbits.de/)
# Damit ist es möglich, APK-Files aus dem Google-Playstore herunterzuladen. Dieses Script sucht
# alle APK-Files heraus und bietet u.a. eine schnelle Auswahl, welche Apps installiert werden sollen.
# Wenn mehrere Geräte an einem USB-Hub angeschlossen sind, kann ausgesucht werden, auf welche
# Geräte die APK-Dateien installiert werden sollen.
# Zum Erstellen eines lokalen Backups muss das Unterverzeichnis "backup" erstellt werden.

#########################################################################################################

#Variablen:
apk="./content/apps/"
backup="./backup"
DATE=`date +%Y-%m-%d_%H%M%S`
_answers="/tmp/answers.$$"
_options="/tmp/options.$$"
_apk="/tmp/apk.$$"
_apk_remove="/tmp/apk_remove.$$"
_apk_restore="/tmp/apk_restore.$$"

#PN=`basename "$0"`
#echo $PN
#dialog >$_answers

########################################################################################

# Cleanup
cleanup(){
# Dateien, in denen die gewaehlten Optionen gespeichert wurden, wieder loeschen:
[ -e $_options     ] && rm -f $_options
[ -e $_answers     ] && rm -r $_answers
[ -e $_apk         ] && rm -f $_apk
[ -e $_apk_remove  ] && rm -f $_apk_remove
[ -e $_apk_restore ] && rm -f $_apk_restore
}
########################################################################################

# APK-Files finden und Liste abspeichern
find_apk(){
 #(neueste) APK-Files im Unterverzeichnis $apk finden :
 find $apk -type f |grep apk | xargs ls -ltr  |awk '{print $9}' >> $_apk
 #"dialog" verlangt drei Argumente. Daher Ergänzung der Liste um "apk" und "on" (default Auswahl)
 sed -i 's/$/ apk on/g' $_apk
}
########################################################################################

# APK-Files finden und installieren
install_apk(){
 OPTIONS=`cat $_apk`
 choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --checklist 'Welche Pakete sollen installiert werden:' 30 125 25 ${OPTIONS}`

 if [ $? -eq 0 ]
 then
  for choice in $choices
 do
   #Anführungszeichen los werden:
   selection=$(echo $choice |sed 's/\"//g')
   while IFS=" " read files dummy; 
   do 
    if [[ $selection = "$files" ]]; then  
    echo adb -s $devID install $files
 #    Scharf stellen:
 ##   adb -s $devID install $files
    #adb uninstall com.apksoftware.compass
   fi
   done < <(cat $_apk)
 done
 #    echo "--------------------------------------------------------------------------------"
 #    read -p "Enter to return to Menu."
 else
     echo "Keine Auswahl! Ende!"
 fi
}


########################################################################################

# UNinstall APK-Files auf Android-Gerät:
uninstall_apk(){
 rm -f $_apk_remove
 $list_packages |awk -F':' '{ print $2 }' >> $_apk_remove
 #"dialog" verlangt drei Argumente. Daher Ergänzung der Liste um "apk" und "off" (default Auswahl)
 sed -i 's/$/ apk off/g' $_apk_remove
 OPTIONS=`cat $_apk_remove`
 choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --checklist "Welche Pakete sollen entfernt werden:" 30 125 25 ${OPTIONS}`

 if [ $? -eq 0 ]
 then
  for choice in $choices
 do
   #Anführungszeichen los werden:
   selection=$(echo $choice |sed 's/\"//g')
   while IFS=" " read files dummy; 
   do 
    if [[ $selection = "$files" ]]; then  
    echo adb -s $devID uninstall $files
 #    Scharf stellen:
 ##   adb -s $devID uninstall $files
   fi
   done < <(cat $_apk_remove)
 done
 #    echo "--------------------------------------------------------------------------------"
 #    read -p "Enter to return to Menu."
 else
     echo "Keine Auswahl! Ende!"
 fi
}

########################################################################################

# Restore des Backups auf ausgewählte Geräte:
restore() {
 #Backups Unterverzeichnis $backup finden und in Liste speichern :
 find $backup/ -type f |grep .ab | xargs ls -ltr  |awk '{print $9}' > $_apk_restore
 #"dialog" verlangt drei Argumente. Daher Ergänzung der Liste um "ab" und "off" (default Auswahl)
 sed -i 's/$/ ab off/g' $_apk_restore
 #cat $_apk_restore

 OPTIONS=`cat $_apk_restore`
 choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --radiolist "Welches Backup soll wiederhergestellt werden:" 30 125 25 ${OPTIONS}`

 if [ $? -eq 0 ]
 then
  for choice in $choices
 do
   #Anführungszeichen los werden:
   selection=$(echo $choice |sed 's/\"//g')
   while IFS=" " read files dummy; 
   do 
    if [[ $selection = "$files" ]]; then  
    echo adb -s $devID restore $files
    #Scharf stellen:
    ##adb -s $devID restore $files
   fi
   done < <(cat $_apk_restore)
 done
 #    echo "--------------------------------------------------------------------------------"
 #    read -p "Enter to return to Menu."
 else
     echo "Keine Auswahl! Ende!"
 fi
}

########################################################################################

### Untermenu erzeugen ###
sub_menu() {

cleanup;
counter=0
while read devID dummy ; do
  [ -z "$devID" -o "$devID" = "List" -o "$devID" = "*" ]  && continue
  counter=$((counter+1))
  echo "$counter $devID on"  >> $_options
done < <( adb devices )

# Alt
#while IFS=";" read devID; do
#  counter=$((counter+1))
#  #Die Checkliste benötigt drei Parameter: Zaehler, Geraete-ID, on (default Vorauswahl)
#  echo "$counter $devID on"  >> $_options
#done < <(eval $list_devices)

OPTIONS=`cat $_options`
choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --checklist 'Welches Geräte sollen verwaltet werden:' 30 75 25 ${OPTIONS}`

#echo "Geräte erfasst..."

find_apk;

if [ $? -eq 0 ]
then
 for choice in $choices
do
  #Anführungszeichen los werden:
  selection=$(echo $choice |sed 's/\"//g')
  while IFS=" " read number devID on; 
  do 
   if [[ $selection = "$number" ]]; then 

   ########################################################################################
   #Vordefinierte Befehle:

   #List Devices:
   list_devices="adb devices | awk '{print \$1}' |tail -n +2";
   #Alle installierten Pakete auf dem Gerät auflisten:
   list_packages="adb -s $devID shell pm list packages"
   #Backup des Systems und der Systemanwendungen:
   backup_sys="adb backup –all –f $backup/backup-sys-$devID-$DATE.ab"
   #Backup des Systems, der Systemanwendungen, Benutzeranwendungen und externen SD Karte:
   backup_all="adb backup –all -apk -shared –f $backup/backup-all-$devID-$DATE.ab"
   #Shell aufrufen: (klappt nicht von "dialog" aus ...)
   shell="adb -s "$devID" shell"
   #Logcat auf Gerät
   logcat="adb -s $devID logcat"

   ########################################################################################

     case $1 in  
       1) install_apk ;;                                                 #Installieren
       2) uninstall_apk ;;                                               #Löschen
       3) echo Gerät $devID:; $list_packages; echo -e "\n";;             #Auflisten
       4) echo $backup_sys; touch $backup/backup-sys-$devID-$DATE.ab;;   #Backup_System
       5) echo $backup_all; touch $backup/backup-all-$devID-$DATE.ab;;   #Backup_All
       6) restore ;;                                                     #Restore
       7) $logcat ;;                                                     #Logcat
       *) cleanup; exit ;;                                               #Exit
      esac

  fi
  done < <(cat $_options)
done
   echo "--------------------------------------------------------------------------------"
   read -p "Enter to return to Menu."
else
    echo "Keine Auswahl! Ende!"
fi
}

##################################################################################

### Hauptmenu ###
main_menu() {
    dialog --backtitle " adb-Manager   Version: $VER " --title "   Hauptmenu   "\
        --cancel-label "Exit" \
        --menu "Cursortasten [UP] [DOWN], [ENTER] zur Auswahl" 15 60 10\
        Installieren "Pakete installieren"\
        Löschen "Pakete löschen"\
        Auflisten "Pakete auflisten"\
        Backup "Backup erstellen (System)"\
        Backup_All "Backup erstellen (Alles)"\
        Restore "Backup zurückspielen"\
        Logcat "dmesg ansehen (nur 1 Gerät möglich)"\
        Quit "Exit" 2>$_answers

    opt=${?}
    if [ $opt != 0 ]; then rm $_answers; exit; fi
    menuitem=`cat $_answers`
    echo "menu=$menuitem"
    #Variable $1 wird mit an das sub_menu uebergeben:
    case $menuitem in
        Installieren) sub_menu 1;;
        Löschen) sub_menu 2;;
        Auflisten) sub_menu 3;;
        Backup) sub_menu 4;;
        Backup_All) sub_menu 5;;
        Restore) sub_menu 6;;
        Logcat) sub_menu 7;;
        Quit) cleanup; exit;;
    esac
}

##################################################################################

### Hauptmenu erzeugen ###
while true; do
   main_menu;
done

#EOF

Ach ja: die eine oder andere Stelle kann man sicher eleganter programmieren. Daher sind natürlich auch alle Verbesserungsvorschläge willkommen. Das schöne an dem modularen Aufbau ist, dass man das Menu jetzt ganz schnell um weitere Funktionen erweitern kann, wie z.B. Zugriff über WiFi oder das Erzeugen/Löschen/Verwalten von weiteren User-Accounts.

Zuletzt noch ein X-Post zum ursprünglichen Artikel, der das ganze ins Rollen gebracht hat.

Schöne Grüße,
Michael


Mobile Device Management für Tablet
#2

Hi zusammen.
Ich kann den alten Artikel nicht mehr bearbeiten – daher poste ich die aktuelle Verison 1.4 nochmal unten drunter.

Mittlerweile habe ich die ersten Tablets mit meinem Script geklont und es lief größtenteils ganz ordentlich. Bei unseren Tablets war es so, dass ich diverse Dateien ohne Problem überschreiben konnte, die ich z.B. auf meinem Smartphone (mit ganz aktuellem Android!) nicht mal mehr lesen konnte. Ich bin nicht weit genug drin, um entscheiden zu können, ob mit neueren Android-Versionen die Sicherheitsmerkmale für adb verschärft wurden, doch ich nehme es mal sehr stark an :interrobang:

Was das Script leisten kann:

  • einheitliche Installation von allen gefundenen .apk Dateien auf allen angeschlossenen Android-Geräten (bei denen USB-Debugging eingeschaltet sein muss)
  • einheitliche Settings in Bezug auf: WLAN, Desktop-Icons, Lock-Settings (bei uns PIN-Eingabe)

Was seltsamerweise nicht gut funktioniert:

  • Full-Backup + Restore (ich habe da einen Workaround eingebaut, der das Backup zunächst auf dem Gerät anlegt und erst dann rüberholt, weil es da immer wieder zu Abbrüchen kam)
  • Deinstallation von Apps (da erhalte ich öfter mal ein “Failed” – die Ursache ist mir nicht klar)

Ich habe das Script natürlich genau auf unsere Bedürfnisse zugeschnitten und habe es im Vergleich zur Version 1.1 von oben weiter mit diversen functions() ausgestattet, so dass man zukünftig auch einfach diese functions direkt hintereinander aufrufen kann, wenn man einen vollständig automatischen Ablauf wünscht. Blöd an Android ist (im Gegensatz zu Apple, wie ich mir sagen lassen habe) die Tatsache, dass man zunächst diverse Schritte in Handarbeit erleidigen muss:

  • Einschalten, den ersten Assistenen abnicken, USB-Debugging aktivieren und Zugriff vom PC erlauben – erst dann kann man wirklich darauf zugreifen.

Hier kommt die aktuelle Fassung – und wie immer gilt: “Wer’s gebrauchen kann: Bitte sehr!” (Lizenz GPLv3)

#!/bin/bash
#set -x

#########################################################################################################
# Scriptname :    adb-manager.sh 
# Licence    :    GPLv3
# Author     :    Demo-Vorlage von Bernd Holzhauer; geändert und angepasst von Michael Hagedorn
# WebSite    :    https://www.cc-c.de/german/linux/linux-dialog.php
# Date       :    2018-07-19
# Requires   :    dialog, adb, adb-tools, USB-Debugging auf Android-Geräten aktiviert
# Category   :    geeignet für Linux zur Verwaltung von Android-Geräten mittels "adb"
# Category   :    Initiative fuer http://www.linuxmuster.net (Verwaltung von Geräten mit adb)
#Version     :
VER='1.4'
#########################################################################################################

# Anleitung : Das Script arbeitet z.B. zusammen mit Raccoon (https://raccoon.onyxbits.de/)
# Damit ist es möglich, APK-Files aus dem Google-Playstore herunterzuladen. Dieses Script sucht
# alle APK-Files im Unterverzeichnis ./content/apps/ heraus und bietet u.a. eine schnelle Auswahl, 
# welche Apps installiert werden sollen.  
# Wenn mehrere Geräte an einem USB-Hub angeschlossen sind, kann ausgesucht werden, auf welche
# Geräte die APK-Dateien installiert werden sollen.
# Zum Erstellen eines lokalen Backups muss das Unterverzeichnis "backup" erstellt werden.

#########################################################################################################

#Variablen:
apk="./content/apps/"
backup="./backup"
DATE=`date +%Y-%m-%d_%H%M%S`
_answers="/tmp/answers.$$"
_options="/tmp/options.$$"
_apk="/tmp/apk.$$"
_apk_remove="/tmp/apk_remove.$$"
_apk_restore="/tmp/apk_restore.$$"

#PN=`basename "$0"`
#echo $PN
#dialog >$_answers

########################################################################################

# Cleanup
cleanup(){
# Dateien, in denen die gewaehlten Optionen gespeichert wurden, wieder loeschen:
[ -e $_options     ] && rm -f $_options
[ -e $_answers     ] && rm -r $_answers
[ -e $_apk         ] && rm -f $_apk
[ -e $_apk_remove  ] && rm -f $_apk_remove
[ -e $_apk_restore ] && rm -f $_apk_restore
}
########################################################################################

# APK-Files finden und Liste abspeichern
find_apk(){
 #(neueste) APK-Files im Unterverzeichnis $apk finden :
 find $apk -type f |grep apk | xargs ls -ltr  |awk '{print $9}' >> $_apk
 #"dialog" verlangt drei Argumente. Daher Ergänzung der Liste um "apk" und "on" (default Auswahl)
 sed -i 's/$/ apk on/g' $_apk
}
########################################################################################

# APK-Files finden und installieren
install_apk(){
 OPTIONS=`cat $_apk`
 choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --checklist 'Welche Pakete sollen installiert werden:' 30 125 25 ${OPTIONS}`

 if [ $? -eq 0 ]
 then
  for choice in $choices
 do
   #Anführungszeichen los werden:
   selection=$(echo $choice |sed 's/\"//g')
   while IFS=" " read files dummy; 
   do 
    if [[ $selection = "$files" ]]; then  
    command="adb -s $devID install -r $files"
 # Option -r -> reinstall (bei Updates)
    echo $command;
 # Scharf stellen:
    $command;
   fi
   done < <(cat $_apk)
 done
 #    echo "--------------------------------------------------------------------------------"
 #    read -p "Enter to return to Menu."
 else
     echo "Keine Auswahl! Ende!"
 fi
}


########################################################################################

# UNinstall APK-Files auf Android-Gerät:
uninstall_apk(){
 rm -f $_apk_remove
 $list_packages |awk -F':' '{ print $2 }' >> $_apk_remove
 #"dialog" verlangt drei Argumente. Daher Ergänzung der Liste um "apk" und "off" (default Auswahl)
 sed -i 's/$/ apk off/g' $_apk_remove
 OPTIONS=`cat $_apk_remove`
 choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --checklist "Welche Pakete sollen entfernt werden:" 30 125 25 ${OPTIONS}`

 if [ $? -eq 0 ]
 then
  for choice in $choices
 do
   #Anführungszeichen los werden:
   selection=$(echo $choice |sed 's/\"//g')
   while IFS=" " read files dummy; 
   do 
    if [[ $selection = "$files" ]]; then  
    command="adb uninstall $files";
    echo $command;
 # Scharf stellen: (Option -s $devID rausgenommen!)
    $command;
   fi
   done < <(cat $_apk_remove)
 done
 #    echo "--------------------------------------------------------------------------------"
 #    read -p "Enter to return to Menu."
 else
     echo "Keine Auswahl! Ende!"
 fi
}

########################################################################################

# Backup auf sdcard & pull:
backup() {
   #Backup des Systems und der Systemanwendungen:
   #backup_sys="./v1.0.31_adb/adb backup '-apk de.rhcsoftware.plnb8' -f ./backup/backup-$DATE.ab";
   #adb backup "-apk -obb -shared -all -system" -f ./backup/backup-$DATE.ab
#Workaround: 
echo Backup wird nach ./backup gesichert!
i=1
for i in $devID
do
adb shell "bu 1 backup -apk de.rhcsoftware.plnb8 > /sdcard/backup.ab"
adb pull /sdcard/backup.ab ./backup/backup-$DATE.ab
echo "Done.";
done
}

########################################################################################

# Restore des Backups auf ausgewählte Geräte:
restore() {
 #Backups Unterverzeichnis $backup finden und in Liste speichern :
 find $backup/ -type f |grep .ab | xargs ls -ltr  |awk '{print $9}' > $_apk_restore
 #"dialog" verlangt drei Argumente. Daher Ergänzung der Liste um "ab" und "off" (default Auswahl)
 sed -i 's/$/ ab off/g' $_apk_restore
 #cat $_apk_restore

 OPTIONS=`cat $_apk_restore`
 choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --radiolist "Welches Backup soll wiederhergestellt werden:" 30 125 25 ${OPTIONS}`

 if [ $? -eq 0 ]
 then
  for choice in $choices
 do
   #Anführungszeichen los werden:
   selection=$(echo $choice |sed 's/\"//g')
   while IFS=" " read files dummy; 
   do 
    if [[ $selection = "$files" ]]; then
    command="adb -s $devID restore $files";
    echo $command;
# Scharf stellen:
    $command;
   fi
   done < <(cat $_apk_restore)
 done
 #    echo "--------------------------------------------------------------------------------"
 #    read -p "Enter to return to Menu."
 else
     echo "Keine Auswahl! Ende!"
 fi
}


#######################################################################################

# Backup der Systemeinstellungen (Desktop, WLAN):
settings() {
echo System-Einstellungen werden nach ./backup gesichert!
i=1
for i in $devID
do
 adb pull /data/data/com.android.launcher3/databases/launcher.db ./backup;
 adb pull /data/misc/wifi/wpa_supplicant.conf ./backup;
 adb pull /data/data/com.android.providers.settings/databases/settings.db ./backup;
 # Passwort/PIN:
 adb pull /data/system/gesture.key ./backup;
 adb pull /data/system/password.key ./backup;
 adb pull /data/system/locksettings.db ./backup;
 adb pull /data/system/locksettings.db-shm ./backup;
 adb pull /data/system/locksettings.db-wal ./backup;
echo "Done.";
done
}

#######################################################################################

# Restore der Systemeinstellungen (Desktop, WLAN):
restore_settings() {
echo System-Einstellungen werden auf Gerät kopiert!
i=1
for i in $devID
do
#WiFi-Settings:
 adb push ./backup/wpa_supplicant.conf /data/misc/wifi/;
 adb shell "chown system:wifi /data/misc/wifi/wpa_supplicant.conf";
 adb shell "chmod 660 /data/misc/wifi/wpa_supplicant.conf";
#-rw-rw---- system   wifi  wpa_supplicant.conf (Rechte)

#Desktop-Icons:
 adb push ./backup/launcher.db /data/data/com.android.launcher3/databases/;
 adb shell "chown u0_a13:u0_a13 /data/data/com.android.launcher3/databases/launcher.db";
 adb shell "chmod 660 /data/data/com.android.launcher3/databases/launcher.db";
# -rw-rw---- u0_a13   u0_a13  launcher.db

#Sicherheitseinstellungen:
 adb push ./backup/settings.db /data/data/com.android.providers.settings/databases/;
 adb shell "chown system:system /data/data/com.android.providers.settings/databases/settings.db";
 adb shell "chmod 660 /data/data/com.android.providers.settings/databases/settings.db";
#-rw-rw---- system   system settings.db (Rechte)

#Gesten-Eingabe:
 adb push ./backup/gesture.key /data/system/;
 adb shell "chown system:system /data/system/gesture.key";
 adb shell "chmod 600 /data/system/gesture.key";

#Passwort/PIN:
 adb push ./backup/password.key /data/system/;
 adb shell "chown system:system /data/system/password.key";
 adb shell "chmod 600 /data/system/gesture.key";
#-rw------- system   system  gesture.key (Rechte)

#Locksettings: 
  adb push ./backup/locksettings.db /data/system/;
  adb shell "chown system:system /data/system/locksettings.db";
  adb shell "chmod 660 /data/system/locksettings.db";
  adb push ./backup/locksettings.db-shm /data/system/;
  adb shell "chown system:system /data/system/locksettings.db-shm";
  adb shell "chmod 660 /data/system/locksettings.db-shm";
  adb push ./backup/locksettings.db-wal /data/system/;
  adb shell "chown system:system /data/system/locksettings.db-wal";
  adb shell "chmod 660 /data/system/locksettings.db-wal";
#-rw-rw---- system   system  locksettings.db*

 adb shell reboot;
 echo "Done.";
done
}

########################################################################################

### Untermenu erzeugen ###
sub_menu() {

cleanup;
counter=0
while read devID dummy ; do
  [ -z "$devID" -o "$devID" = "List" -o "$devID" = "*" ]  && continue
  counter=$((counter+1))
  echo "$counter $devID on"  >> $_options
done < <( adb devices )

# Alt
#while IFS=";" read devID; do
#  counter=$((counter+1))
#  #Die Checkliste benötigt drei Parameter: Zaehler, Geraete-ID, on (default Vorauswahl)
#  echo "$counter $devID on"  >> $_options
#done < <(eval $list_devices)

OPTIONS=`cat $_options`
choices=`/usr/bin/dialog --backtitle " adb-Manager   Version: $VER" --stdout --checklist 'Welches Geräte sollen verwaltet werden:' 30 75 25 ${OPTIONS}`

#echo "Geräte erfasst..."

find_apk;

if [ $? -eq 0 ]
then
 for choice in $choices
do
  #Anführungszeichen los werden:
  selection=$(echo $choice |sed 's/\"//g')
  while IFS=" " read number devID on; 
  do 
   if [[ $selection = "$number" ]]; then 

   ########################################################################################
   #Vordefinierte Befehle:

   #List Devices:
   list_devices="adb devices | awk '{print \$1}' |tail -n +2";
   #Alle installierten Pakete auf dem Gerät auflisten:
   list_packages="adb -s $devID shell pm list packages"
   #Shell aufrufen: (klappt nicht von "dialog" aus ...)
   shell="adb -s "$devID" shell"
   #Logcat auf Gerät
   logcat="adb -s $devID logcat"

   ########################################################################################

     case $1 in  
       1) install_apk ;;                                                 #Installieren
       2) uninstall_apk ;;                                               #Löschen
       3) echo Gerät $devID:; $list_packages; echo -e "\n";;             #Auflisten
       4) backup ;;                                                      #Backup_System
       5) restore ;;                                                     #Restore_System
       6) settings ;;                                                    #Backup_Settings
       7) restore_settings ;;                                            #Restore_Settings
       8) $logcat ;;                                                     #Logcat
       *) cleanup; exit ;;                                               #Exit
      esac

  fi
  done < <(cat $_options)
done
   echo "--------------------------------------------------------------------------------"
   read -p "Enter to return to Menu."
else
    echo "Keine Auswahl! Ende!"
fi
}

##################################################################################

### Hauptmenu ###
main_menu() {
    dialog --backtitle " adb-Manager   Version: $VER " --title "   Hauptmenu   "\
        --cancel-label "Exit" \
        --menu "Cursortasten [UP] [DOWN], [ENTER] zur Auswahl" 16 60 10\
        Installieren "Pakete installieren"\
        Löschen "Pakete löschen"\
        Auflisten "Pakete auflisten"\
        Backup "Backup erstellen (System)"\
        Restore "Backup zurückspielen"\
        Settings "Einstellungen sichern (Desktop, WiFi)"\
        Copy "Einstellungen kopieren (Desktop, WiFi)"\
        Logcat "dmesg ansehen (nur 1 Gerät möglich)"\
        Quit "Exit" 2>$_answers

    opt=${?}
    if [ $opt != 0 ]; then rm $_answers; exit; fi
    menuitem=`cat $_answers`
    echo "menu=$menuitem"
    #Variable $1 wird mit an das sub_menu uebergeben:
    case $menuitem in
        Installieren) sub_menu 1;;
        Löschen) sub_menu 2;;
        Auflisten) sub_menu 3;;
        Backup) sub_menu 4;;
        Restore) sub_menu 5;;
        Settings) sub_menu 6;;
        Copy) sub_menu 7;;
        Logcat) sub_menu 8;;
        Quit) cleanup; exit;;
    esac
}

##################################################################################

### Hauptmenu erzeugen ###
while true; do
   main_menu;
done

#EOF

Wer Verbesserungsvorschläge hat: Immer gerne!
Übrigens: Der Programmier-Style ist ganz sicher nicht der Weisheit letzter Schluss … aber “works for me” :slight_smile:

Schöne Grüße,
Michael