Запустить скрипт bash при входе в систему, хранящуюся в домашней папке?


18

Когда я пытаюсь загрузить список запуска LaunchAgent, launchctlя не могу узнать, как запустить скрипт в домашнем каталоге.

Мой код:

<?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>ProgramArguments</key>
    <array>
        <string>bash</string>
        <string>~/script.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>Label</key>
    <string>com.tyilo.test</string>
</dict>
</plist>

Я пробовал как с и без Баш, а также заменить ~на $HOME. Я также пытался использовать bash -cбез него работает.

Код ошибки:

`com.tyilo.test: bash: ~/script.sh: No such file or directory`

Попробуйте указать полный путь, например /Users/name/script.sh (также я бы сделал сценарий исполняемым и с первой строкой #! / Bin / bash и запустил бы его напрямую)
Отметьте

Я не могу использовать полный путь, так как он должен использоваться на нескольких учетных записях и компьютерах.
Tyilo

1
Если он будет использоваться для нескольких моих учетных записей, вы должны поместить его в / usr / local / bin /, а не делать несколько копий в $ HOME каждого пользователя. Было бы полезно узнать, чего вы пытаетесь достичь с помощью этого скрипта. Это звучит как работа для LoginHook, IMO.
TJ Luoma

Ответы:


13

EnableGlobbingвключает расширение тильды и подстановочных знаков для ProgramArguments:

<key>EnableGlobbing</key>
<true/>
<key>ProgramArguments</key>
<array>
    <string>say</string>
    <string>~/*</string>
</array>

Это не влияет Programили WatchPaths, однако, расширение тильды работает WatchPathsпо умолчанию.


Это лучший способ сделать это. Есть ли место, где вы можете просмотреть документацию для ключей в списке LaunchAgent?
Tyilo

man launchd.plist. Или посмотрите этот пост в блоге или мой сайт .
Lri

1
Это мне тоже помогло. Пробовал в следующих версиях Mac OS X: 10.7, 10.8 и 10.9.
DJ S

6
Обратите внимание: эта функция была удалена в Yosemite ( Mac OS X 10.10+).
Алекс

Похоже, что это не в 10.9.5 либо
ocodo

17

EnableGlobbing не работает на OS X Yosemite 10.10 . Это устарело ( ref ).

Вы можете увидеть в журналах The EnableGlobbing key is no longer respected. Please remove it./var/log/system.log)

Проблема в том, что launchdcwd (текущий рабочий каталог) есть /, поэтому вы не можете использовать, ./как говорили некоторые люди.

Для запуска сценария из вашего дома простой способ заключается в использовании (bash|zsh|sh) -c. вариант. Таким образом, у вас будет возможность использовать тильду ~или $HOMEпеременную.

<?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>org.your.stuff</string>
    <key>ProgramArguments</key>
    <array>
      <!-- here is the important thing -->
      <string>zsh</string>
      <string>-c</string>
      <string>~/you/script/in/your/home</string>
    </array>

    <!-- code below is just for the example -->
    <!-- Keep running... -->
    <key>KeepAlive</key>
    <true />
    <!-- ...every day. In sec, 60*60*24 = every day -->
    <key>ThrottleInterval</key>
    <integer>86400</integer>
  </dict>
</plist>

2
Я не думаю, что вы можете использовать тильду с sh; когда Bash задействован как sh, он работает в режиме совместимости с POSIX, который отключает многие расширения Bash.
tripleee

~/жадно так не поддерживается. Вы можете использовать ./вместо этого, пока демон сохраняется в домашней библиотеке пользователей. ( ~/Library/LaunchAgents)
Бруно

8

Самый надежный я нашел делать это с помощью shи с HOMEпеременной Enviroment:

<?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>ProgramArguments</key>
    <array>
        <string>sh</string>
        <string>-c</string>
        <string>"$HOME/script.sh"</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>Label</key>
    <string>com.tyilo.test</string>
</dict>
</plist>

Примечание: цитаты обязательны.


2

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

user=`whoami`

Затем используйте $userв сценарии.

Я бы действительно поставил скрипт где-то, кроме домашней директории, тогда он будет доступен другим пользователям на том же компьютере. Вы можете использовать общий каталог или поместить скрипт в / Library / Scripts /

Вы должны будете использовать полный путь к списку запусков. Кроме того, в вашем файле launchd plist вам не нужно указывать, <string>bash</string>поскольку у вас должен быть шебанг в скрипте, и он должен быть исполняемым.


Указание bashв качестве фактической команды для выполнения является хорошим запасным вариантом без реального ущерба. Если у него нет шебанга или он забывает сделать скрипт исполняемым (o = rwx), то bash все равно вызовет / выполнит скрипт.
Джейсон Салаз

1
Для имени пользователя уже должна быть переменная, например, $ USER или $ LOGNAME. Кроме того, обычным местом для общих сценариев Unix будет / usr / local / bin / (не то, чтобы вы не могли поместить их в другое место, но / usr / local / bin /, скорее всего, уже будет в вашем $ PATH).
TJ Luoma

Использование whoami - это просто еще один способ получить ту же информацию, что и $ USER или $ LOGNAME. Я предложил местоположения выше, поскольку я не хотел предполагать что-либо от спрашивающего. Кроме того, прежде чем пытаться заставить launchd plist работать, скрипт должен быть в состоянии запускаться из CLI.
afragen

1

Если ваш сценарий является агентом пользователя (и, следовательно, находится в библиотеке домашней папки), launchdтекущим рабочим каталогом является домашняя папка. UNIX относится к домашнему каталогу с точкой в ​​пути.

Так что в основном используйте ./script.shвместо ~/script.sh. ;-)


3
Нет, рабочий каталог launchd на самом деле /не '~'.
Tyilo

@ Тыло Я не уверен, что ты имеешь в виду. Если вы имеете в виду «рабочий каталог launchd является корневым, во всех случаях - даже в пользовательском режиме», предоставьте ссылку. Если вы имеете в виду «launchd использует косую черту вместо тильды», прочитайте мой пост еще раз. Кстати, у меня есть несколько сценариев, запланированных в launchd, и они следуют за поведением, которое я описываю. ;-)
Константино Царухас

1
@RandyMarch я сделал запуск агента ~/Library/LaunchAgentsс аргументами: sh, -c, echo $HOME > /Users/Tyilo/launchd_home.txt. Когда запускается файл, /Users/Tyilo/launchd_home.txtсодержащийся /, нет /Users/Tyilo.
Tyilo

0

Это исполняемый файл?

chmod 700 ~/script.sh

в Терминале. Кроме того, я бы не использовал $ HOME или ~, а скорее фактический путь к файлу.

<?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.tyilo.test</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/script.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

В чем причина понижения голоса?
TJ Luoma
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.