как заставить сценарии оболочки запускаться при запуске на Yosemite

Я предполагаю, что в System/Library есть каталог для элементов автозагрузки: StartupItems

Мне нужен сценарий оболочки, который будет настраивать интерфейс Ethernet при запуске с локальным сетевым адресом и маской подсети. Мне нужно сделать это, потому что сетевые настройки для настройки интерфейса Ethernet НЕ будут устанавливать его с помощью ручных настроек. ЭТО кажется серьезной ошибкой, или моя установка плохая.

Мне дали совет использовать networksetup из командной строки, но это не настроит интерфейс Ethernet таким образом, чтобы конфигурации были там при перезагрузке.

Сценарий должен выполнять свою работу с привилегиями root или с помощью sudo, но я предполагаю, что если он использует sudo, во время загрузки будет отображаться диалоговое окно с паролем, когда процесс загрузки доберется до этого сценария.

(У меня было достаточно опыта работы с FreeBsd и Linux, чтобы ориентироваться в терминале, но не обязательно, поскольку это применимо к Mac OSX)

Ответы (3)

Один из способов сделать это — назначить скрипту службу запуска:

Создайте сценарий оболочки, как обычно. Затем вы можете создать службу launchd для ее запуска при запуске. Те находятся по адресу /Library/LaunchDaemons. Они представлены в формате списка свойств XML. Создайте еще один и заполните его примерно так:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.example.app</string>
        <key>ProgramArguments</key>
        <array>
            <string>/bin/sh</string>
            <string>/path/to/script</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <false/>
    </dict>
</plist>

Меняйте com.example.appи /bin/shпо /path/to/scriptмере необходимости.

Затем скрипт будет работать во время загрузки системы. Если он запускается слишком рано, вы можете либо написать сценарий, чтобы он пытался делать то, что ему нужно, пока не добьется успеха, либо завершить его с ненулевым кодом ошибки и добавить его в список свойств перед </dict>строкой:

<key>KeepAlive</key>
<dict>
     <key>SuccessfulExit</key>
     <false/>
</dict>

Чтобы узнать больше о демонах и службах запуска OS X, я предлагаю посмотреть здесь хороший краткий справочник по их созданию или здесь более полный справочник о том, что может сделать launchd.

Как вы называете этот plist-документ? И есть ли /path/to/script == /System/Library/StartupItems/script?
По первому вопросу: имя документа plist обычно использует то, что установлено для ключа Label в списке свойств (в данном случае «com.example.app») с расширением .plist.
По второму вопросу: это правильно, но сценарий следует перенести в другое место.
Ваш plist имеет неверный формат. Вам нужен ключ: <key>Program</key>со значением, <string>/bin/sh</string>а затем <key>ProgramArguments</key>должен просто иметь значение<string>/path/to/script</string>
На самом деле, мой тоже ошибается: <key>ProgramArguments</key>должен быть массив..

Некоторое время назад я использовал cron для этого. Вы можете сделать запись, как это

@reboot /path/to/my/script

Подробнее здесь

Вместо первых пяти полей может появиться одна из восьми специальных строк:

       string          meaning
       ------          -------@reboot ------@reboot
       @reboot         Run once, at startup.
       @yearly         Run once a year, "0 0 1 1 *".
       @annually       (same as @yearly)
       @monthly        Run once a month, "0 0 1 * *".
       @weekly         Run once a week, "0 0 * * 0".
       @daily          Run once a day, "0 0 * * *".
       @midnight       (same as @daily)
       @hourly         Run once an hour, "0 * * * *".
Очень полезно знать!
cronэто неправильный способ сделать это в OS X в наши дни. Вместо этого используйте LaunchAgent или LaunchDeamon (launchd). Для получения дополнительной информации: developer.apple.com/library/mac/documentation/MacOSX/Conceptual/… Although it is still supported, cron is not a recommended solution. It has been deprecated in favor of launchd.
cronоднако его намного проще настроить launchd, чем . Просто сравните два ответа в этой теме, чтобы понять, что я имею в виду. cronзанимает одну строку в одном файле, где launchdнужен сценарий для описания сценария, который вы хотите запускать при загрузке.
@Dannid Kron не чувствителен к дублированию запуска, буферизации очереди и другим. Несмотря на то, что в данном случае это жизнеспособно, это не всегда отмычка и не идиоматическое решение.
Кронтаб намного лучше. Это быстро, грязно и давно зарекомендовало себя в мире Unix. Я полностью копаю это ключевое слово @reboot.
@macetw В идеале да. И да, это давно установлено в мире Unix. Однако, возможно, он устарел в macOS и был в течение некоторого времени. Вы никогда не знаете, что делать с устаревшими вещами: может быть время, когда они больше не поддерживаются. И да , @reboot полезен, и это то, что есть в некоторых других Unices, но все же рекомендовать что-то, что устарело, глупо. Жаль, что он устарел? Да. Особенно для тех из нас, кто старожилы. Но это все еще так, как есть. Очень похоже на пародию на systemd... Но неважно.

Взгляните на сценарий входа в систему.

https://wiki.afp548.com/index.php/Login/Logout_Hooks_in_OS_X

Ловушка входа инициируется loginwindow.app, что не то же самое, что запуск скрипта при запуске.