🍺

Invalid usage: `brew services` is supported only on macOS or Linuxの解決

2021/11/14に公開

3行でまとめ

pyenv由来のWarning: "config" scripts exist outside your system対策のために入れたPATHの設定が原因で、brew servicesが動かなくなっちゃいました。

.zshrc (NG版)
alias brew="PATH=/opt/homebrew/bin brew"

これで直りました。

.zshrc (OK版 anyenvなし)
alias brew="env PATH=${PATH/\/Users\/${USER}\/\.pyenv\/shims:/} brew"
.zshrc (OK版 anyenvあり)
alias brew="env PATH=${PATH/\/Users\/${USER}\/\.anyenv\/envs\/pyenv\/shims:/} brew"

はじめに

M1 Macを買いまして、あえて最初からコツコツ開発環境構築をしておるんですが、
brew install postgresqlしたあとPostgreSQLが自動起動せずちょいとハマりました。

/opt/homebrew/opt/postgresql/bin/postgres -D /opt/homebrew/var/postgres

こう叩いてやるとちゃんと起動するんですが、
brew services経由での自動起動がうまくいかない。
というか、そもそもbrew services自体が動いてないのでPostgreSQLの問題ではない。

$ brew services
Usage: brew services [subcommand]

Manage background services with macOS' launchctl(1) daemon manager.

If sudo is passed, operate on /Library/LaunchDaemons (started at boot).
Otherwise, operate on ~/Library/LaunchAgents (started at login).

[sudo] brew services [list]:
    List all managed services for the current user (or root).

[sudo] brew services run (formula|--all):
    Run the service formula without registering to launch at login (or boot).

[sudo] brew services start (formula|--all):
    Start the service formula immediately and register it to launch at login
(or boot).

[sudo] brew services stop (formula|--all):
    Stop the service formula immediately and unregister it from launching at
login (or boot).

[sudo] brew services restart (formula|--all):
    Stop (if necessary) and start the service formula immediately and register
it to launch at login (or boot).

[sudo] brew services cleanup:
    Remove all unused services.

      --file                       Use the plist file from this location to
                                   start or run the service.
      --all                        Run subcommand on all services.
  -d, --debug                      Display any debugging information.
  -q, --quiet                      Make some output more quiet.
  -v, --verbose                    Make some output more verbose.
  -h, --help                       Show this message.

Error: Invalid usage: `brew services` is supported only on macOS or Linux (with systemd)!

エラーメッセージが不親切なんですよね。思いっきりmacOSやっちゅーねん!
sudo brew servicesならちゃんと動くんですが、
sudoつけると意味が違ってしまうので、sudoつけずに普通に動かしたい。

コード読んでみる

エラー出してるのはここ。
https://github.com/Homebrew/homebrew-services/blob/0bae398d93f530230857aed8d23e5a99d90b14a8/cmd/services.rb#L54-L57

    if !Service::System.launchctl? && !Service::System.systemctl?
      raise UsageError,
            "`brew services` is supported only on macOS or Linux (with systemd)!"
    end

if文の条件になってるメソッドはここ。
https://github.com/Homebrew/homebrew-services/blob/0bae398d93f530230857aed8d23e5a99d90b14a8/lib/service/system.rb#L9-L27

    # Path to launchctl binary.
    def launchctl
      @launchctl ||= which("launchctl")
    end

    # Is this a launchctl system
    def launchctl?
      launchctl.present?
    end

    # Path to systemctl binary.
    def systemctl
      @systemctl ||= which("systemctl")
    end

    # Is this a systemd system
    def systemctl?
      systemctl.present?
    end

launchctlがMac用、systemctlがLinux用のコマンドで、どちらもPATHが通ってないとエラーになるわけですね。
試しにwhich launchctlを手動で叩いてみると、ちゃんと存在する。

$ which launchctl
/bin/launchctl

が、ここで思い出しました!前日にbrew doctorのwarning対策でちょいとPATHいじったことを。

brew doctor でWarning: "config" scripts exist outside your system と出る件の対処をしていた

anyenv経由でpyenvを入れたら、brew doctorでwarningが出るようになってしまい、この記事を参考にbrew実行時のPATHを変更してwarningを出なくしたのでした。
https://zenn.dev/ryuu/scraps/fddefc2ca60f88

.zshrc
alias brew="PATH=/opt/homebrew/bin brew"

これがダメでした。
お分かりだと思いますが、こうすると「他のPATHを一切見なくなってしまう」わけです。
当然/bin/launchctlも見つからないわけで、そのせいでbrew servicesが実行できないんですね。これならdoctorでwarning出る方がまだマシでした。

解決方法

https://www.テクめも.com/entry/pyenv-brew-doctor
https://github.com/pyenv/pyenv/issues/106#issuecomment-94921352
こっちの方法で、既存のPATHもちゃんと維持されていい感じに動くようになりました。

載ってるサンプルコードは、anyenvを介さずにpyenvだけで入れた場合のもの。

.zshrc
alias brew="env PATH=${PATH/\/Users\/${USER}\/\.pyenv\/shims:/} brew"

anyenvを介す場合は、pyenvのパスも変わるので、こうすればOKです。

.zshrc
alias brew="env PATH=${PATH/\/Users\/${USER}\/\.anyenv\/envs\/pyenv\/shims:/} brew"

ちなみに、試行錯誤中にsudo brew services start postgresqlしちゃったせいで、root権限でログが作成されてしまって別のエラーが出ていたので、ログを一度消したらうまく行きました。

sudo rm /opt/homebrew/var/log/postgres.log

Discussion