Как я могу запускать ruby-скрипт от имени пользователя root каждые 10 секунд на Mac?

У меня есть следующее в моем /Library/LaunchDemons как com.me.filechecker.plist

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!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>File Checker</string>
        <key>StartInterval</key>
        <integer>10</integer>
        <key>Program</key>
        <string>/usr/bin/ruby "/Users/me/projects/filechecker/filechecker.rb"</string>
    </dict>
</plist>

я тоже побежал

sudo chown root /Library/LaunchDaemons/com.me.filechecker.plist

а также

sudo chmod a+x /Library/LaunchDaemons/com.me.filechecker.plist

а также

sudo launchctl load -w /Library/LaunchDaemons/com.me.filechecker.plist

Похоже, он не работает (или если он работает, он ничего не делает). Как я могу отладить это и заставить его работать?


person Some Guy    schedule 10.05.2015    source источник
comment
Какие permissions вы установили для скрипта, и пробовали ли вы также запустить его как cronjob, возможно? Еще одна мысль — подумайте также о публикации ruby script; может проблема в скрипте.   -  person l'L'l    schedule 10.05.2015
comment
Запускаются ли cronjobs от имени пользователя root? Если да, что мне сделать, чтобы добавить его в качестве cronjob, и будет ли он запускаться автоматически каждый раз, когда я запускаю свой компьютер? Разрешения a+x chmodded.   -  person Some Guy    schedule 10.05.2015
comment
Файл имеет разрешения... -rwxr-xr-x@ 1 root колесо 458 10 мая 11:36 com.me.filechecker.plist (IDK что такое колесо)   -  person Some Guy    schedule 10.05.2015
comment
Эти разрешения обычно подходят для cronjobs или daemons. cronjobs может использовать разрешения в соответствии с тем, что пользователю нужно для запуска задачи, она также будет запускаться автоматически при запуске компьютера, поэтому она довольно гибкая. Ваш скрипт работает нормально, когда вы запускаете его из Terminal.app, и что он делает? Как я упоминал ранее, вы можете опубликовать сценарий, чтобы мы могли увидеть, что именно он делает. Также попробуйте эту команду в терминале: ps aux | grep filechecker - вы видите что-нибудь в списке?   -  person l'L'l    schedule 10.05.2015
comment
wheel — это имя специальной группы пользователей, к которой принадлежит пользователь root. См. superuser.com/a/191969/139307. .   -  person mklement0    schedule 12.05.2015
comment
Для тех, кто отвечает, а также для будущих читателей: если ответ решает вашу проблему, примите его, щелкнув большую галочку рядом с ним; если вы найдете ответ полезным, пожалуйста, проголосуйте за него, щелкнув значок со стрелкой вверх (вы можете сделать и то, и другое). См. соответствующую статью справочного центра. Если на ваш вопрос еще нет ответа, оставьте отзыв.   -  person mklement0    schedule 12.05.2015
comment
Я еще не проверял. Дай мне немного времени.   -  person Some Guy    schedule 14.05.2015


Ответы (2)


Имя исполняемого файла и его аргументы следует передавать так же, как и execvp. Вы должны передать имя исполняемого файла и все аргументы отдельно. Аргументы должны передаваться в ключе ProgramArguments:

    <key>Program</key>
    <string>/usr/bin/ruby</string>
    <key>ProgramArguments</key>
    <array>
       <string>/usr/bin/ruby</string>
       <string>/Users/me/projects/filechecker/filechecker.rb</string>
    </array>

Вы также можете пропустить ключ Program в этом случае. Подробнее в man launchd.plist

 Program <string>
 This key maps to the first argument of execvp(3).  If this key is missing, then the first element of
 the array of strings provided to the ProgramArguments will be used instead.  This key is required in
 the absence of the ProgramArguments key.

 ProgramArguments <array of strings>
 This key maps to the second argument of execvp(3).  This key is required in the absence of the Program
 key. Please note: many people are confused by this key. Please read execvp(3) very carefully!
person baf    schedule 10.05.2015
comment
Хороший совет, но вы не должны заключать в двойные кавычки значение второго элемента <string> - оболочка не задействована, поэтому удаление кавычек не выполняется. С кавычками они становятся частью самого аргумента. - person mklement0; 10.05.2015
comment
@mklement0 Исправлено. Спасибо! - person baf; 10.05.2015
comment
P.S.: Я бы сказал, что для простоты обычно лучше использовать только ключ ProgramArguments. - person mklement0; 11.05.2015

Чтобы дополнить полезный ответ baf (который показывает, как использовать ключ ProgramArguments для правильного вызова исполняемого файла с аргументами):

Хотя создание исполняемого файла *.plist не должно причинить вреда, в этом нет необходимости.
Важно то, что файл:

  1. должен принадлежать пользователю, в контексте которого выполняется задание (что вы сделали с sudo chown root, хотя sudo chown root:wheel лучше для согласованности).
  2. не должен быть доступным для групповой или общей записи из соображений безопасности; таким образом, типичный файл в /Library/LaunchDaemons, чьи *.plist файлы запускаются от имени пользователя root (по умолчанию), сообщает следующее в начале строки вывода из ls -l: -rw-r--r-- 1 root wheel ...

launchctl load, к сожалению, генерирует сообщение об ошибке только в том случае, если файл *.plist синтаксически неверен, и обычно всегда устанавливает код выхода 0, даже в случае ошибки.

Чтобы устранить неполадки, откройте Console.app и найдите com.apple.xpc.launchd записей:

Если я сделаю это после загрузки вашего файла *.plist, я увижу несколько соответствующих записей, в частности эту:

5/10/15 11:33:38.653 PM com.apple.xpc.launchd[1]: (File Checker[61800]) 
Could not find and/or execute program specified by service: 2: 
No such file or directory: /usr/bin/ruby "/Users/me/projects/filechecker/filechecker.rb"

Это говорит нам о том, что launchd считает путь исполняемого файла целой строкой /usr/bin/ruby "/Users/me/projects/filechecker/filechecker.rb", потому что ключ Program должен только содержать путь к исполняемому файлу.

С исправлением, предложенным ответом baf, launchd должен правильно вызывать команду.

person mklement0    schedule 11.05.2015