Czy uruchomić skrypt bash przy logowaniu zapisanym w folderze domowym?

19

Kiedy próbuję załadować listę LaunchAgent z, launchctlnie mogę dowiedzieć się, jak uruchomić skrypt w katalogu domowym.

Mój kod to:

<?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>

Próbowałem zarówno z jak i bez bash, a także wymianie ~z $HOME. Próbowałem też używać bash -cbez tego.

Kod błędu to:

`com.tyilo.test: bash: ~/script.sh: No such file or directory`
Tyilo
źródło
Spróbuj wstawić pełną ścieżkę, np. /Users/name/script.sh (Chciałbym również, aby skrypt był wykonywalny i w pierwszym wierszu #! / Bin / bash i uruchomić go bezpośrednio)
user151019
Nie mogę użyć pełnej ścieżki, ponieważ ma być używana na wielu kontach i komputerach.
Tyilo
1
Jeśli ma być używane moje wiele kont, powinieneś umieścić go w / usr / local / bin / zamiast robić wiele jego kopii w $ HOME każdego użytkownika. Przydałoby się wiedzieć, co próbujesz osiągnąć za pomocą tego skryptu. Brzmi jak praca dla LoginHook, IMO.
TJ Luoma,

Odpowiedzi:

14

EnableGlobbingumożliwia rozszerzenie tyldy i symboli wieloznacznych dla ProgramArguments:

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

To nie ma wpływu Programlub WatchPathsjednak tyldy działa WatchPathsdomyślnie.

Lri
źródło
To zdecydowanie lepszy sposób na zrobienie tego. Czy jest miejsce, w którym można wyświetlić dokumentację kluczy w liście LaunchAgent?
Tyilo,
człowiek launchd.plist. Lub zobacz ten post na blogu lub moją stronę internetową .
Lri
1
To mi też pomogło. Próbowałem w następujących wersjach systemu Mac OS X: 10.7, 10.8 i 10.9.
Dj S
6
Uwaga: Ta funkcja została usunięta z Yosemite ( Mac OS X 10.10+).
Alex Grey
Wygląda na to, że nie ma go również w
10.9.5
18

EnableGlobbing nie działa w systemie OS X Yosemite 10.10 . To jest przestarzałe ( ref ).

Możesz zobaczyć w logach The EnableGlobbing key is no longer respected. Please remove it.(od /var/log/system.log)

Problem polega na tym, że launchdcwd (bieżący katalog roboczy) jest /, więc nie możesz używać, ./jak niektórzy mówią.

Aby uruchomić skrypt z domu, najprostszym sposobem jest użycie (bash|zsh|sh) -c. opcja. W ten sposób będziesz mieć możliwość użycia tyldy ~lub $HOMEzmiennej.

<?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>
MoOx
źródło
2
Nie sądzę, że można użyć tyldy sh; gdy Bash jest zaangażowany jako sh, działa w trybie zgodności z POSIX, który wyłącza wiele rozszerzeń Bash.
tripleee
~/jest pożeraniem, więc nie jest obsługiwane. Możesz użyć ./zamiast tego, dopóki demon jest zapisany w domowej bibliotece użytkowników. ( ~/Library/LaunchAgents)
Bruno
9

Najbardziej niezawodny znalazłem robi to był za pomocą sha HOMEzmiennej środowiska spowodowanego:

<?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>

Uwaga: cytaty są wymagane.

Tyilo
źródło
2

Pomocne byłoby wiedzieć, dlaczego skrypt musi być uruchamiany z katalogu domowego użytkownika. Jeśli potrzebujesz skróconej nazwy użytkownika dla skryptu, możesz ją zdobyć, przypisując ją do zmiennej jak w

user=`whoami`

Następnie użyj $userw skrypcie.

Naprawdę umieściłbym skrypt w innym miejscu niż katalog domowy, a następnie byłby dostępny dla innych użytkowników na tym samym komputerze. Możesz użyć katalogu współdzielonego lub umieścić skrypt w / Library / Scripts /

Będziesz musiał użyć pełnej ścieżki do uruchomionego plist. Ponadto w uruchomionej liście nie musisz określać, <string>bash</string>ponieważ powinieneś mieć shebang w skrypcie i powinien on być wykonywalny.

afragen
źródło
Określenie bashrzeczywistego polecenia do wykonania jest dobrą rezerwą bez rzeczywistej szkody. Jeśli nie ma shebang lub zapomni, aby skrypt był wykonywalny (o = rwx), wtedy bash będzie nadal wywoływał / wykonywał skrypt.
Jason Salaz
1
Powinna już istnieć zmienna dla nazwy użytkownika, taka jak $ USER lub $ LOGNAME. Ponadto, zwykłą lokalizacją współdzielonych skryptów uniksowych będzie / usr / local / bin / (nie to, że nie można ich umieścić gdzie indziej, ale / usr / local / bin / najprawdopodobniej będzie już w twojej $ PATH).
TJ Luoma,
Korzystanie z whoami to kolejna metoda uzyskiwania tych samych informacji, co $ USER lub $ LOGNAME. Zasugerowałem powyższe lokalizacje, ponieważ nie chciałem zakładać niczego o pytającego. Ponadto, zanim spróbujesz uruchomić uruchomiony plist, skrypt faktycznie musi być w stanie uruchomić się z CLI.
afragen
1

Czy to jest wykonywalne?

chmod 700 ~/script.sh

w terminalu. Ponadto nie użyłbym $ HOME lub ~, ale raczej rzeczywistą ścieżkę do pliku.

<?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
źródło
Jaki jest powód głosowania?
TJ Luoma,
1

Jeśli skrypt jest agentem użytkownika (a zatem znajduje się w bibliotece folderu domowego), launchdbieżącym katalogiem roboczym jest folder domowy. UNIX odnosi się do katalogu domowego z kropką w ścieżce.

Zasadniczo używaj ./script.shzamiast ~/script.sh. ;-)

Constantino Tsarouhas
źródło
3
Nie, faktycznie działającym katalogiem uruchomionego jest /, a nie „~”.
Tyilo,
@Tyilo Nie jestem pewien, co masz na myśli. Jeśli masz na myśli, że „katalogiem roboczym uruchomionego jest katalog główny, we wszystkich przypadkach - nawet w trybie użytkownika”, podaj odniesienie. Jeśli masz na myśli „launchd używa ukośnika zamiast tyldy”, przeczytaj mój post jeszcze raz. Nawiasem mówiąc, mam zaplanowanych kilka skryptów, które działają zgodnie z opisanym przeze mnie zachowaniem. ;-)
Constantino Tsarouhas
1
@RandyMarch zrobiłem środek uruchomienie w ~/Library/LaunchAgentsz argumentami: sh, -c, echo $HOME > /Users/Tyilo/launchd_home.txt. Kiedy prowadził plik /Users/Tyilo/launchd_home.txtzawierał /nie /Users/Tyilo.
Tyilo,