Запустити bash скрипт при вході, що зберігається в домашній папці?


19

Коли я намагаюся завантажити список запуску 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>

Я спробував і з, і без bash, а також замінив ~на $HOME. Я також спробував використовувати, bash -cне працюючи.

Код помилки:

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

Спробуйте ввести повний шлях, наприклад /Users/name/script.sh (Також я зробив би сценарій виконуваним і з першого рядка #! / Bin / bash та запустив його безпосередньо)
user151019

Я не можу використовувати повний шлях, оскільки він повинен бути використаний на кількох облікових записах і на комп’ютерах.
Тайло

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

Відповіді:


14

EnableGlobbingдозволяє розширити тильди та підстановки для ProgramArguments:

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

Це не впливає Programабо WatchPaths, проте, розширення тильди працює WatchPathsза замовчуванням.


Це кращий спосіб зробити це. Чи є місце, де можна переглянути документацію для ключів у списку LaunchAgent?
Тайло

man startd.plist. Або побачити цей блог або мій сайт .
Лрі

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

6
Зверніть увагу: Ця функція була видалена в Yosemite ( Mac OS X 10.10+).
alex grey

Схоже, це не в 10.9.5
окудо

18

EnableGlobbing не працює на OS X Yosemite 10.10 . Він застарілий ( відмітка) ).

Ви можете бачити в журналах 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.
трійчарник

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

9

Найбільш надійним, що мені вдалося зробити це, було за допомогою 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>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в сценарії.

Я справді поставив би сценарій де-небудь, крім домашнього каталогу, тоді він доступний іншим користувачам на тому ж комп’ютері. Ви можете скористатися каталогом Спільне або поставити сценарій у / Бібліотека / Сценарії /

Вам доведеться використовувати повний шлях для запущеного списку. Крім того, у вашому запущеному плісті вам не потрібно буде вказувати, <string>bash</string>як у вас повинен бути шебанг в сценарії, і він повинен бути виконаним.


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

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

Використання whoami - це лише інший метод отримання тієї самої інформації, що і US USER або $ LOGNAME. Я запропонував розташування вище, тому що я не хотів нічого припускати, що ставить запитання. Також перед тим, як спробувати змусити роботу запущеного списку, сценарій насправді повинен мати змогу запускатися з CLI.
afragen

1

Це виконується?

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

1

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

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


3
Ні, робоча директорія запускається насправді /, а не '~'.
Тиїло

@Tyilo Я не впевнений, що ти маєш на увазі. Якщо ви маєте на увазі "робочий каталог запуску - це корінь, у всіх випадках - навіть у режимі користувача", будь ласка, надайте посилання. Якщо ви маєте на увазі "startd використовує косу рису замість тильди", прочитайте мій пост ще раз. До речі, у мене є кілька сценаріїв, запланованих у запуску, і вони слідують за поведінкою, яку я описую. ;-)
Константіно Царухас

1
@RandyMarch я зробив запуск агента ~/Library/LaunchAgentsз аргументами: sh, -c, echo $HOME > /Users/Tyilo/launchd_home.txt. Коли запускається файл, що /Users/Tyilo/launchd_home.txtміститься /, не /Users/Tyilo.
Тиїло
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.