Je veux supprimer un certain nombre d'applications sur un appareil Android qui commencent toutes par le même package. Je les reçois avec la command suivante:
$ adb shell ls /data/data | grep -i com.company com.company.android.app.adwidget com.company.android.app.attendancereports com.company.android.app.atteventmanagement com.company.android.app.buttonwidget com.company.android.app.clockwidget
Maintenant je veux exécuter la adb uninstall
pour chacun de ces noms de packages, j'ai pensé à utiliser xargs
:
$ adb shell ls /data/data | grep -i com.company | xargs -n1 echo adb uninstall adb uninstall com.company.android.app.adwidget adb uninstall com.company.android.app.attendancereports adb uninstall com.company.android.app.atteventmanagement adb uninstall com.company.android.app.buttonwidget adb uninstall com.company.android.app.clockwidget
On dirait que ça va marcher, alors je retire l' echo
:
$ adb shell ls /data/data | grep -i com.company | xargs -n1 adb uninstall Failure Failure Failure Failure Failure
Cependant, exécuter chaque command génère un Success
:
$ adb uninstall com.company.android.app.adwidget Success
Qu'est-ce que je fais mal?
Bien que le problème ait été causé par des caractères CR dans la sortie du adb shell
(inséré par la discipline tty line du pty créé sur le système Android cible (voir ici pour plus de détails)), une autre explication possible il pour les lecteurs à venir que c'est un problème commun avec xargs
) aurait pu être que:
adb shell ls /data/data | grep -i com.company | xargs -n1 adb uninstall
en fonction de l'implémentation de xargs
, le stdin d' adb
sera soit /dev/null
soit le pipe de grep
. Dans tous les cas, ce ne sera pas le tty et c'est peut-être la raison adb
laquelle adb
échouera s'il espère pouvoir interagir avec l'user.
Avec GNU xargs
et un shell xargs
en charge la substitution de process (comme zsh
), vous pouvez le changer en:
xargs -n1 -ra <(adb shell ls /data/data | grep -i com.company) adb uninstall
Dans ce cas, xargs
lit la list du file donné en argument à -a
ce qui vous permet de ne plus utiliser stdin.
Ou puisque vous mentionnez zsh
, vous pouvez utiliser:
autoload zargs # best in ~/.zshrc zargs -L1 $(adb shell ls /data/data | grep -i com.company) -- adb uninstall
(en utilisant -L
au lieu de -n
comme zargs
-n
limite le nombre total d'arguments à adb
(y compris la uninstall
) ce qui signifie que nous aurions besoin de -n 2
).
Ou utilisez simplement une boucle, qui serait encore plus courte et plus lisible dans ce cas:
for x ($(adb shell ls /data/data | grep -i com.company)) adb uninstall $x
Rediriger la sortie de l' adb shell ls /data/data | grep -i com.company
de commands adb shell ls /data/data | grep -i com.company
adb shell ls /data/data | grep -i com.company
à un file et en l'examinant avec un hexeditor, j'ai découvert qu'ils sont ajoutés avec le return chariot de style Windows \r\n
(0x0D 0x0A). Donc se débarrasser de la \r
avec tr -d '\r'
résolu le problème.
Commande entière utilisant for
(de la réponse de Stéphane Chazelas ):
for x in $(adb shell ls /data/data | grep -i com.company | tr -d '\r'); do adb uninstall $x; done
Ou de manière similaire en utilisant xargs
:
adb shell ls /data/data | grep -i com.company | tr -d '\r' | xargs -r -n1 adb uninstall
Une autre option (comme aimablement expliquée par Stéphane Chazelas sur les commentaires ci-dessous) est désactivée avec stty -opost
, bien que cela nécessite probablement busybox
(ou une alternative comme toybox
) pour être installé sur le périphérique Android.
$ adb shell echo test | sed -nl test\r$ $ adb shell 'busybox stty -opost; echo test' | sed -nl test$