В документации Homebrew указаны два стандартных префикса: /opt/homebrew для Apple Silicon и /usr/local для Intel Mac (FAQ Homebrew о путях установки). Сначала выясните, под каким пользователем и в каком Shell выполняется команда, затем проверьте фактический префикс и загрузку brew shellenv. Если обычный терминал находит команду, а SSH или CI — нет, исправляйте окружение именно этого запуска, а не повторяйте установку и не меняйте права наугад.

Сначала соберите факты в одной проблемной сессии. На этой неделе закрепите диагностику в SSH-команде или журнале CI, чтобы повторный сбой можно было сравнить с исправным запуском.

Это руководство для разработчиков, которые подключаются к удалённому Mac по SSH и не могут вызвать Homebrew или установленную программу.
Оно также пригодится инженерам, поддерживающим macOS CI, фоновые задачи и общую учётную запись разработчика.

01

Ошибка на уровне brew, программы или задания

Сообщение «команда не найдена» само по себе не доказывает, что установка Homebrew повреждена. Сбой может возникать на разных уровнях. Если не разделить их, легко исправить PATH для одного Shell, но оставить CI без нужной программы.

Сначала зафиксируйте четыре наблюдения: точную команду и полный текст ошибки, пользователя, способ запуска и имя Shell. Не ограничивайтесь снимком экрана интерактивного терминала. Сопоставьте запуск в терминале, через SSH-команду и в автоматической задаче, если именно там проявляется проблема.

Затем определите, какой именно случай у вас:

  • Не вызывается brew. Проверяйте путь к исполняемому файлу и PATH текущего Shell.
  • brew запускается, но установленная программа — нет. Проверьте, установлена ли программа через Homebrew в доступном этому пользователю префиксе и включён ли её каталог в PATH.
  • Вручную команда работает, а задание падает. Сравните пользователя, Shell и переменные окружения задания с SSH-сессией.
  • Команда найдена, но завершается ошибкой доступа. Исследуйте владельца и права каталогов; это уже не обычная ошибка поиска команды.

Для начальной диагностики используйте команды в том же контексте, где воспроизводится сбой:

whoami
echo "$SHELL"
printf '%s\n' "$PATH"
command -v brew

$SHELL показывает оболочку, записанную для учётной записи, но не всегда подтверждает, какой Shell запустил конкретный процесс. Поэтому сопоставьте его с настройками SSH-команды, скрипта или сервиса. command -v также проверяет поиск команды текущей оболочкой, а не наличие пакета в базе Homebrew.

Так вы избежите ошибочного вывода «Homebrew не установлен», когда он просто отсутствует в PATH автоматической задачи. Если удалённая машина ещё не настроена для работы, сначала сверяйтесь с порядком подготовки и приёмки среды удалённого Mac, а не копируйте конфигурацию другого пользователя.

02

Фактический префикс и архитектура Mac

Стандартные пути из документации — ориентир, а не результат измерения вашей машины. Основной источник истины — команды на удалённом хосте. Под нужной учётной записью выполните:

command -v brew
brew --prefix
brew config
brew doctor

Если command -v brew ничего не возвращает, остальные команды, начинающиеся с brew, ожидаемо не запустятся. Сначала найдите исполняемый файл в известном для этой установки месте или проверьте конфигурацию Shell. Не добавляйте оба стандартных префикса в PATH «на всякий случай»: так можно скрыть установку второй копии Homebrew и вызывать не тот экземпляр.

Если brew запускается, brew --prefix сообщит активный префикс. Сравните его с выводом brew config и архитектурой машины. У Homebrew стандартный префикс для Apple Silicon отличается от стандартного префикса для Intel; эти значения и обоснование расположения описаны в официальном FAQ и руководстве по установке. При этом фактический путь зависит от конкретной установки. Не подменяйте проверку удалённого хоста предположением по модели Mac.

Для понимания того, что именно делает Homebrew, пригодится официальная справка по командам: в частности, описание --prefix, shellenv и команд диагностики. Если команда уже находится, но поведение пакета отличается от ожидаемого, сверяйте вывод brew doctor с разделом Homebrew по распространённым проблемам. Диагностическое предупреждение не означает автоматически, что нужно менять права или переустанавливать пакет; сначала установите связь предупреждения с конкретной ошибкой.

Проверьте и программу, ради которой вы начали расследование:

command -v имя_команды
brew list --versions имя_пакета

Подставьте реальные имя программы и имя пакета: они могут различаться. Если пакет установлен, но исполняемый файл не находится, определите, куда его устанавливает формула и какой каталог должен быть виден в PATH. Не делайте вывод об успешной установке только по наличию записи в списке пакетов: нужен запуск самой команды в нужной среде.

03

SSH, Shell и загрузка brew shellenv

Интерактивный терминал и удалённая команда по SSH могут читать разные файлы конфигурации. Поэтому проверка в окне терминала не подтверждает, что инициализация Homebrew выполняется при запуске скрипта или команды без интерактивной сессии.

Для zsh официальная документация описывает отдельные файлы запуска для разных режимов; например, конфигурация интерактивной оболочки не равнозначна конфигурации, которую читает неинтерактивный процесс (файлы запуска zsh). Не переносите строку настройки из .zshrc в конфигурацию другого Shell, не проверив, что именно запускает удалённая задача. Для Bash и других оболочек также проверяйте документацию соответствующего Shell и фактические параметры запуска.

Сначала выполните диагностику через тот же способ подключения, который падает:

ssh пользователь@хост 'whoami; echo "$SHELL"; printf "%s\n" "$PATH"; command -v brew'

Замените имя пользователя и адрес хоста своими значениями. Если Shell не находит brew, но вы знаете фактический префикс, проверьте исполняемый файл напрямую. Затем получите вывод настройки окружения:

/путь/к/brew shellenv

Подставьте реальный путь, найденный на машине. Команда печатает настройки, которые нужно применить к окружению; сам факт её выполнения ещё не означает, что переменные останутся установленными в родительской оболочке. Выберите файл инициализации с учётом режима запуска и конкретного Shell, добавьте минимально необходимую настройку, откройте новую сессию и повторите проверку. Не добавляйте одну и ту же строку в несколько файлов без причины: дубли усложняют поиск источника PATH и могут привести к вызову не той установки.

Частые вопросы

Почему SSH не находит brew, хотя в терминале команда работает?

Удалённая команда может выполняться с другим набором переменных или в другом режиме Shell. Проверьте whoami, фактический Shell и PATH непосредственно внутри SSH-команды. Если путь Homebrew существует, но не входит в PATH этой сессии, настройте инициализацию для используемого режима. Сверяйте результат новой SSH-командой, а не уже открытым терминалом.

Как подтвердить путь Homebrew на Apple Silicon и Intel?

Запустите brew --prefix под учётной записью, где возник сбой, и сопоставьте результат с brew config. Документация указывает разные стандартные префиксы для Apple Silicon и Intel, но это не гарантирует, что данная машина использует именно стандартное расположение. Если brew не находится, установите реальный путь к исполняемому файлу до настройки PATH.

04

Контекст CI и фоновых задач

Когда команда работает в SSH, но падает в CI, планировщике или службе, диагностируйте процесс задания. Ручной запуск под административной учётной записью ничего не доказывает о переменных и правах фонового процесса. Его может запускать отдельный пользователь, другой Shell или сервис с ограниченным окружением.

Добавьте временный диагностический блок непосредственно в задание. Запишите имя текущего пользователя, значение SHELL, PATH, результат command -v brew, вывод brew --prefix и код завершения тестовой команды. Не выводите секреты окружения целиком: для этой проверки достаточно перечисленных значений. По журналу определите, выполняется ли ожидаемый скрипт и дошёл ли он до этапа вызова инструмента.

Результат проверки Вероятная причина Следующее действие
Не находится brew ни в SSH, ни в задании Префикс или настройка PATH неверны для учётной записи Найдите исполняемый файл и настройте нужный Shell
brew доступен в SSH, но не в задаче Отличается пользователь, Shell или окружение сервиса Исправьте конфигурацию запуска задания и проверьте его журнал
brew доступен, но целевая программа — нет Пакет не установлен для активного префикса или путь программы не виден Проверьте список пакетов и каталог исполняемого файла
Команда найдена, но получает отказ в доступе Несовпадение владельца или разрешений Проверьте владельца и права затронутых каталогов

Для сервисного Runner используйте его журналы и процедуру диагностики, а не только вывод собственного терминала. Документация по мониторингу и устранению неполадок самостоятельных Runner описывает проверку процесса и сервисного контекста. Здесь важен общий принцип: подтверждение должно быть получено из задачи, которая действительно выполняется на вашем Mac.

Дальше исправляйте только найденное расхождение. Если задание запускается под отдельной учётной записью, убедитесь, что Homebrew и нужный пакет доступны ей в предусмотренном для этой машины режиме. Если сервис запускает другой Shell, настройте окружение этого запуска или явно подготовьте PATH в скрипте задания. Не полагайтесь на конфигурацию профиля администратора, которую сервис не читает.

Как понять, какой Shell и пользователь используются в CI?

Добавьте в задание вывод whoami, SHELL, PATH и command -v brew, затем изучите его журнал. Сверьте результат с настройками службы и параметрами запуска Runner. Переменная SHELL полезна, но при диагностике учитывайте и команду-оболочку, которой фактически запускается скрипт. Проверка должна выполняться самим заданием, а не вручную в соседней SSH-сессии.

Что менять, если проблема встречается только в автоматическом задании?

Оставьте установку без изменений, пока журнал не покажет обратное. Если целевой исполняемый файл существует, а проблема сводится к PATH или режиму запуска Shell, исправьте скрипт задания либо конфигурацию его службы. Повторите задание и подтвердите в логе пользователя, путь к brew и успешный запуск целевой команды. Переустановка оправдана лишь при подтверждённо повреждённом или недоступном экземпляре.

05

Права, владелец и границы исправления

Отказ в доступе — отдельный симптом. Если brew находится, но не запускается или не может читать файлы, сначала проверьте владельца префикса и права именно тех каталогов, на которые указывает ошибка:

ls -ld "$(brew --prefix)"
ls -l "$(command -v brew)"

При сбое чтения или выполнения пакета изучите также путь к его исполняемому файлу. Проверьте, совпадает ли владелец с ожидаемой учётной записью и не запускается ли Homebrew из-под пользователя, который не должен управлять этой установкой.

Homebrew отдельно описывает модель учётных записей и административные границы в руководстве для администраторов Mac. Сверьте рекомендации с назначением хоста и принятой моделью доступа. Не запускайте рекурсивное изменение владельца для всего префикса как универсальный рецепт: оно может затронуть файлы, управляемые другой учётной записью, и замаскировать исходное расхождение. Не включайте глобальный sudo для команд Homebrew без подтверждённой необходимости.

Преимущество ограниченного исправления — вы не меняете состояние всей машины из-за одной задачи. Недостаток — сначала нужно точно выявить объект с неверным владельцем или режимом доступа. Если установка общая, согласуйте границы владения с тем, кто обслуживает Mac, и зафиксируйте, какая учётная запись устанавливает и обновляет пакеты. Если такой модели нет, сначала восстановите её, а не добавляйте новые исключения в правах.

06

Повторная проверка и решение по узлу

После изменения не ограничивайтесь тем, что команда заработала в текущем окне. Закройте тестовую сессию и проведите проверки в каждом контексте, где команда нужна: в целевом Shell, через SSH и в реальном CI или фоновом задании. Если ошибка относится только к одному заданию, исправляйте его окружение; если недостоверны установка, префикс или базовая конфигурация узла — решайте вопрос о восстановлении среды или замене узла.

Перед закрытием инцидента отметьте пункты:

  • [ ] Зафиксированы исходная команда, полный текст ошибки и способ запуска.
  • [ ] Подтверждён пользователь, который выполняет проблемную команду.
  • [ ] Установлен фактический Shell, а не только предполагаемая оболочка.
  • [ ] Проверены command -v brew, brew --prefix и PATH в проблемном контексте.
  • [ ] Для установленной программы подтверждены наличие пакета и доступность исполняемого файла.
  • [ ] Проверены владелец и права только тех каталогов, которые связаны с ошибкой.
  • [ ] После правки новая SSH-сессия и фактическое автоматическое задание завершились ожидаемо.
  • [ ] В журнале сохранены пути и результаты, достаточные для сравнения при повторном сбое.

Для повторяемой работы храните команды диагностики рядом со скриптом сборки, но не записывайте в журнал секреты или полное окружение процесса. Если чините общую среду удалённой разработки, отделите документацию пользователя от конфигурации сервисной учётной записи. Материалы о ценах аренды Mac mini помогут оценить вариант отдельного узла, когда текущую машину нельзя надёжно привести к согласованной базовой конфигурации.

Локальная настройка удобна, если проблема ограничена одним скриптом и у вас есть контроль над аккаунтом и запуском задачи. У неё есть и обратная сторона: скрытые различия PATH между пользователями, ручное обслуживание зависимостей и риск, что обновление конфигурации затронет чужой процесс. Покупка собственного Mac уместна, если вам нужна постоянная машина под вашим физическим контролем; но тогда обслуживание, доступность и обновление узла остаются на вашей стороне.

Если стабильного Mac для воспроизведения и проверки ошибки нет, можно рассмотреть аренду удалённого Mac от VpsMesh: это даёт отдельную среду для SSH и CI без немедленной покупки оборудования. Такой вариант не заменит собственный узел там, где критичны физический доступ, локальные периферийные устройства или постоянная нагрузка под вашим контролем. Сначала проверьте условия оформления аренды Mac mini, а решение принимайте по требованиям к доступу и обслуживанию, а не только по текущей ошибке Homebrew.