xargsが正しいコマンドを生成しない

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

私は何が間違っていましたか?

ベストアンサー1

質問は最終的にadb shell出力のCR文字が原因で発生(ターゲットAndroidシステムで生成されたptyのttyラインルールを介して挿入されます(参照)ここ詳しくは))もう一つの可能​​な説明(よくある質問なので今後読者のために残しておきますxargs)は次のとおりです。

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

xargs実装に応じて、adb標準入力は/dev/nullパイプまたはパイプから出ますgrep。とにかくttyではないadbので、ユーザーと対話できると予想されると失敗する理由かもしれません。

GNUxargsとプロセスの交換をサポートするシェル(例zsh:)を使用すると、次のように変更できます。

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

この場合、xargs引数として提供されたファイルからリストを読み取るので、-astdinをそのまま残すことができます。

または言及した後、次のものをzsh使用できます。

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

-L代わりに制限を使用してください-nzargs-nみんな引数の数adb(1つを含むuninstall、つまりが必要であることを意味する-n 2)。

あるいは、単にループを使用すると、より短くて明確になります。

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

おすすめ記事