xargs не генерирует правильную команду

Я хочу удалить несколько приложений на устройстве Android, которые начинаются с того же пакета. Я получаю их со следующей командой:

$ 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 

Теперь я хочу выполнить adb uninstall для каждого из этих имен пакетов, я думал об использовании 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 

Похоже, что это сработает, поэтому я удаляю echo :

 $ adb shell ls /data/data | grep -i com.company | xargs -n1 adb uninstall Failure Failure Failure Failure Failure 

Однако запуск каждой команды независимо дает Success :

 $ adb uninstall com.company.android.app.adwidget Success 

Что я делаю не так?

2 Solutions collect form web for “xargs не генерирует правильную команду”

Хотя проблема оказалась вызвана символами CR в выводе adb shell (вставлена ​​дисциплина tty line из pty, созданной в целевой системе Android (подробнее см. Здесь )), другое возможное объяснение (и я уйду это для будущих читателей, поскольку это общая проблема с xargs ), возможно, это было в:

 adb shell ls /data/data | grep -i com.company | xargs -n1 adb uninstall 

в зависимости от реализации xargs , stdin adb будет либо /dev/null либо pipe из grep . В любом случае это не будет tty, и может быть, почему adb терпит неудачу, если он ожидает, что сможет взаимодействовать с пользователем.

С GNU xargs и оболочкой с поддержкой подстановки процесса (например, zsh ) вы можете изменить ее на:

 xargs -n1 -ra <(adb shell ls /data/data | grep -i com.company) adb uninstall 

В этом случае xargs считывает список из файла, указанного в качестве аргумента, в -a который позволяет вам оставить stdin в покое.

Или, поскольку вы упоминаете zsh , вы можете использовать:

 autoload zargs # best in ~/.zshrc zargs -L1 $(adb shell ls /data/data | grep -i com.company) -- adb uninstall 

(используя -L вместо -n как zargs 's -n ограничивает общее количество аргументов для adb (включая uninstall ), что означает, что нам понадобится -n 2 ).

Или просто используйте цикл, который будет еще короче и разборчивым в этом случае:

 for x ($(adb shell ls /data/data | grep -i com.company)) adb uninstall $x 

Перенаправление вывода adb shell ls /data/data | grep -i com.company adb shell ls /data/data | grep -i com.company в файл и изучив его с помощью hexeditor, я обнаружил, что они добавлены с возвратом каретки в стиле Windows \r\n (0x0D 0x0A). Поэтому избавление от \r с tr -d '\r' решило проблему.

Целая команда, использующая for (из ответа Стефана Хазеласа ):

 for x in $(adb shell ls /data/data | grep -i com.company | tr -d '\r'); do adb uninstall $x; done 

Или аналогично с помощью xargs :

 adb shell ls /data/data | grep -i com.company | tr -d '\r' | xargs -r -n1 adb uninstall 

Еще один вариант (как это объясняет Стефан Chazelas по комментариям ниже) отключает \r целом со stty -opost , хотя это, скорее всего, требует установки на Android-устройстве busybox (или альтернативы, такой как toybox ).

 $ adb shell echo test | sed -nl test\r$ $ adb shell 'busybox stty -opost; echo test' | sed -nl test$ 
  • Регистрация всех входных и выходных данных в zsh по требованию
  • Заменить строку в команде, которая будет выполнена в zsh
  • Почему вырезать провал с bash, а не zsh?
  • Изменение шаблонов гвоздики zsh для использования с cp
  • Почему zsh (oh-my-zsh) заполняет каталоги, которые не существуют?
  • сделать мой режим отображения zsh в режиме vi
  • Запустите git fetch после любой команды cd
  • ZSH, конкатенация передается аргументами в одну строку
  • Как работать с именами файлов, содержащими одну цитату внутри функции завершения zsh?
  • ZSH: история поиска по клавишам вверх и вниз?
  • Выполнение zsh rehash после сборки
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.