🕵️

mas listがmacOSの更新でエラーを出すようになってしまったので対応する

に公開
4

tl;dr

mas-list
#!/usr/bin/env bash

mdfind -onlyin /Applications 'kMDItemAppStoreHasReceipt=1' \
  | xargs -I{} mdls -attr kMDItemAppStoreAdamID -attr kMDItemDisplayName -attr kMDItemVersion '{}' \
  | sed -E 's/.* = |"|\.app//g' \
  | xargs -d '\n' -n 3 sh -c 'echo "$1/$2/($3)"' - \
  | column -s / -t

経緯

masというcliツールがあります。Mac App Storeとのやり取りを行うツールで、筆者は主にmas listを使っていました。

https://github.com/mas-cli/mas

これがmacOS15.4の更新で動かなくなってしまいました。

https://github.com/mas-cli/mas/issues/724

対応

Apple側の変更で動作しなくなってしまったものは仕方がありません。こちらのページを参考にして、似た動きをするmas-listスクリプトを作成しました。

https://rcmdnk.com/blog/2016/02/23/computer-mac-homebrew-brew-file/

macアプリのメタデータを確認するmdlsコマンドを使うと、App Store経由で導入したアプリはkMDItemAppStoreHasReceiptというフラグが立っていることが確認できます。別経路で入れたアプリの場合はこのキー自体が存在しないようです。

$ mdls /Applications/RunCat.app
# 略...
kMDItemAppStoreHasReceipt                   = 1
# 略...

したがって、クエリを用いてアプリを抽出するmdfindコマンドにこの条件を渡して/Applicationsディレクトリを検索することで、App Store経由のアプリを絞り込むことができます。

$ mdfind -onlyin /Applications 'kMDItemAppStoreHasReceipt=1'
/Applications/Shareful.app
/Applications/Folder Peek.app
/Applications/Color Picker.app
/Applications/Bitwarden.app
/Applications/Pure Paste.app
/Applications/Yomu.app
/Applications/Amazon Kindle.app
/Applications/MenubarX.app
/Applications/Command X.app
/Applications/CenterMouse.app
/Applications/Battery Line.app
/Applications/RunCat.app
/Applications/Gifski.app

これらのそれぞれにmdlsを適用して、必要なメタデータを取り出します。この際、xargs -I{} ... '{}'で行を丸ごとクォートに入れないと、アプリ名がスペースを含むときにエラーになります。

$ mdfind -onlyin /Applications 'kMDItemAppStoreHasReceipt=1' \
  | xargs -I{} mdls -attr kMDItemAppStoreAdamID -attr kMDItemDisplayName -attr kMDItemVersion '{}'
kMDItemAppStoreAdamID = 1575588022
kMDItemDisplayName    = "MenubarX.app"
kMDItemVersion        = "1.7.5"
kMDItemAppStoreAdamID = 1522267256
kMDItemDisplayName    = "Shareful.app"
kMDItemVersion        = "1.11.0"
kMDItemAppStoreAdamID = 1615988943
# 略…

あとは整形です。まずsedで不要な部分を切り落とします。

$ mdfind -onlyin /Applications 'kMDItemAppStoreHasReceipt=1' \
  | xargs -I{} mdls -attr kMDItemAppStoreAdamID -attr kMDItemDisplayName -attr kMDItemVersion '{}' \
  | sed -E 's/.* = |"|\.app//g'
1575588022
MenubarX
1.7.5
1522267256
Shareful
1.11.0
# 略…

これらは「ストアID」「アプリ名」「バージョン」の順に並んでいるので、xargsで3行ごとにまとめます。区切りはアプリ名に使われない文字が良いと思ったので、ここでは/を使いました。バージョンを括弧でくくっているのはもともとのmas listの出力形式に倣ったためです。

$ mdfind -onlyin /Applications 'kMDItemAppStoreHasReceipt=1' \
  | xargs -I{} mdls -attr kMDItemAppStoreAdamID -attr kMDItemDisplayName -attr kMDItemVersion '{}' \
  | sed -E 's/.* = |"|\.app//g' \
  | xargs -d '\n' -n 3 sh -c 'echo "$1/$2/($3)"' -
1575588022/MenubarX/(1.7.5)
1522267256/Shareful/(1.11.0)
# 略…

最後にcolumnで区切りをタブ文字に切り替えて並べます。

$ mdfind -onlyin /Applications 'kMDItemAppStoreHasReceipt=1' \
  | xargs -I{} mdls -attr kMDItemAppStoreAdamID -attr kMDItemDisplayName -attr kMDItemVersion '{}' \
  | sed -E 's/.* = |"|\.app//g' \
  | xargs -d '\n' -n 3 sh -c 'echo "$1/$2/($3)"' - \
  | column -s / -t
1575588022  MenubarX      (1.7.5)
1522267256  Shareful      (1.11.0)
# 略…

あとは、以上のワンライナーをスクリプトに保存して実行権限をつければOKです。冒頭のファイルを再掲します。

mas-list
#!/usr/bin/env bash

$ mdfind -onlyin /Applications 'kMDItemAppStoreHasReceipt=1' \
  | xargs -I{} mdls -attr kMDItemAppStoreAdamID -attr kMDItemDisplayName -attr kMDItemVersion '{}' \
  | sed -E 's/.* = |"|\.app//g' \
  | xargs -d '\n' -n 3 sh -c 'echo "$1/$2/($3)"' - \
  | column -s / -t

感想

筆者はアプリのインストールやアンインストール等は手動で行っており、masは専らApp Store経由で導入したアプリの確認に用いていました。Homebrewなど、他の経路でアプリをダウンロードすることも多くあるためです。
今回作ったスクリプトで、mas listのユースケースは代替できました。mac純正コマンドなので当面は使えるでしょう。たぶん。
masいままでありがとう…!

$ brew rm mas
Uninstalling /opt/homebrew/Cellar/mas/1.9.0... (8 files, 2.4MB)

Discussion

kkddkkdd

こんにちは。
私もmas listが同様にエラーとなりました(下記の2台)。issue として登録されているようですね。

$ sw_vers | grep ProductVersion
ProductVersion:		15.4
$ sw_vers | grep ProductVersion
ProductVersion:		14.7.5
kkddkkdd

こんにちは。
GNU 版 xargs を利用する必要がありますね(gxargs -d ... を動かすために)。