1 votos

Copia de seguridad de todos los apks del dispositivo usando adb: ¿por qué este bucle en bash script no funciona?

Puedes hacer adb shell pm list packages y después de leer la lista, haga un adb shell pm path "com.yourpackage" para obtener la ruta completa y hacer un simple adb pull .

El hecho es: Quiero automatizar esto. Pensé en un muy simple bash script:

for apk in $(adb shell pm list packages | sed 's/package://g' | sort); do
    # If you just do an echo, IT WORKS
    # echo $apk
    # But here it doesn't work
    adb shell pm path $apk
done

Pero eso simplemente no funciona. Parece que "$apk" se convierte en perdido o algo así y no se muestra nada en ese fragmento. No sé si es un problema de subshell, o alguna peculiaridad al usar variables que pasaron por un adb shell.

¿Debo crear un script apks.sh sólo usando pm list para y tal, empujarlo a mi dispositivo, ejecutar adb shell sólo una vez y ejecutar apks.sh?

0 votos

Intente encerrar los parámetros entre comillas: adb shell "pm path $apk" y ver si eso funciona. Citándolo así queda claro que hay que pasarlo todo a adb shell . Sin las comillas, no está claro si el $apk es el segundo parámetro de pm o el 5º parámetro a adb ;)

0 votos

El culpable es que pm list packages , al igual que pm path [PACKAGE] , hace que la salida vaya precedida de la indicación " paquete: ". Una forma de evitar esto sería iterar a través de la cadena pm list packages con algo como lo siguiente: for i in $(pm list packages); do . Luego, dentro del bucle, definirás una variable var con el contenido de i como en: var=$i . A continuación, recortará el " paquete: " con var="${var#p*:}" que devolverá el nombre del paquete. Después de eso, pase var a través de pm path como en: pm path $var y recorte " paquete: " una vez más.

0 votos

En cuanto a su pregunta, supongo que la variable apk pertenece sólo a la terminal de Linux. En la línea 4, está tratando de pasar apk a la pm como si fuera una variable del shell de Android.

4voto

Firelord Puntos 161

No funciona porque adb añade el retorno de carro en la salida. Se puede leer La respuesta de Gilles para más información al respecto.

Todo lo que tienes que hacer es quitar el retorno de carro. Aquí está el script ajustado suyo:

#!/bin/bash

for package in $(adb shell pm list packages | tr -d '\\r' | sed 's/package://g'); do
    apk=$(adb shell pm path $package | tr -d '\\r' | sed 's/package://g');
    echo "Pulling $apk";
    adb pull -p "$apk";
done

Puede utilizar -p con adb pull si sólo tienes la versión 1.0.32 o superior de adb. sort no es necesario, tal y como yo lo veo.

3voto

Carlos Puntos 86

He derivado un comando bash de una línea de La impresionante respuesta de Firelord :

for package in $(adb shell pm list packages -3 | tr -d '\r' | sed 's/package://g'); do apk=$(adb shell pm path $package | tr -d '\r' | sed 's/package://g'); echo "Pulling $apk"; adb pull -p $apk "$package".apk; done

Cambios/mejoras de la versión original:

  • Sólo hace copias de seguridad de las aplicaciones de terceros, porque no veo el sentido de hacer copias de seguridad de las aplicaciones integradas. Sin embargo, si quieres hacer una copia de seguridad de las aplicaciones del sistema también, simplemente omite el -3 bandera.
  • Cambia el nombre de todos los apks por su nombre de paquete en lugar de sobrescribir el mismo base.apk en Android 6.0 "Marshmallow" y superior.

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X