Executar script bash no login armazenado na pasta inicial?


19

Quando tento carregar um plist do LaunchAgent, launchctlnão consigo descobrir como executar um script no diretório inicial.

Meu código é:

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

Eu tentei com e sem bash e também substituindo ~por $HOME. Eu também tentei usar bash -csem ele funcionar.

O código de erro é:

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

Tente colocar o caminho completo, por exemplo /Users/name/script.sh (Também gostaria de tornar o script executável e com a primeira linha #! / Bin / bash e executá-lo diretamente!)
user151019

Não consigo usar o caminho completo, pois ele deve ser usado em várias contas e computadores.
Tyilo

1
Se for para usar minhas múltiplas contas, você deve colocá-lo em / usr / local / bin / em vez de fazer várias cópias no $ HOME de cada usuário. Seria útil saber o que você está tentando realizar com este script. Parece um trabalho para um LoginHook, IMO.
TJ Luoma

Respostas:


14

EnableGlobbingpermite expansão til e curinga para ProgramArguments:

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

Não afeta Programou WatchPaths, no entanto, a expansão til funciona WatchPathspor padrão.


Esta é a maneira muito melhor de fazer isso. Existe um lugar onde você pode visualizar a documentação para as chaves em uma lista do LaunchAgent?
Tyilo 8/03/13

homem launchd.plist. Ou consulte esta postagem do blog ou meu site .
Lri

1
Isso me ajudou também. Tentei nas seguintes versões do Mac OS X: 10.7, 10.8 e 10.9.
Dj S

6
Observação: esse recurso foi removido no Yosemite ( Mac OS X 10.10+).
9135 alex alex

Parece que também não está no
10.9.5

18

EnableGlobbing não funciona no OS X Yosemite 10.10 . Foi preterido ( ref ).

Você pode ver nos logs The EnableGlobbing key is no longer respected. Please remove it.(de /var/log/system.log)

O problema é que o launchdcwd (diretório de trabalho atual) é /, então você não pode usar ./como algumas pessoas disseram.

Para executar um script em sua casa, a maneira mais simples é usar (bash|zsh|sh) -c. opção. Dessa forma, você poderá usar o til ~ou a $HOMEvariável.

<?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
Eu não acho que você pode usar til com sh; quando o Bash está envolvido sh, ele é executado no modo de compatibilidade POSIX, que desativa muitas extensões do Bash.
tripleee

~/está devorando, então não é suportado. Você pode usar ./, desde que o daemon seja salvo na biblioteca inicial do usuário. ( ~/Library/LaunchAgents)
Bruno

9

O mais confiável que encontrei ao fazer isso foi usar sha HOMEvariável de ambiente:

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

Nota: as cotações são obrigatórias.


2

Seria útil saber por que o script precisa ser executado no diretório inicial do usuário. Se você precisar do nome abreviado do usuário para o script, poderá obtê-lo atribuindo-o a uma variável como em

user=`whoami`

Em seguida, use $userno script.

Eu realmente colocaria o script em outro lugar que não seja um diretório pessoal, para que ele possa ser acessado por outros usuários no mesmo computador. Você pode usar o diretório compartilhado ou colocar o script em / Library / Scripts /

Você precisará usar o caminho completo para a lista de inicialização. Além disso, no seu launchd plist, você não precisará especificar <string>bash</string>como deve ter o shebang no script e deve ser executável.


Especificar bashcomo o comando realmente a ser executado é um bom retorno, sem prejuízo real. Se ele não possui o shebang ou se esquece de tornar o script executável (o = rwx), o bash ainda invocará / executará o script.
21412 Jason Salaz

1
Já deve haver uma variável para o nome de usuário, como $ USER ou $ LOGNAME. Além disso, o local usual para scripts Unix compartilhados seria / usr / local / bin / (não que você não possa colocá-los em outro lugar, mas / usr / local / bin / provavelmente já estará no seu $ PATH).
TJ Luoma

Usar whoami é apenas outro método para obter as mesmas informações que $ USER ou $ LOGNAME. Sugeri os locais acima, pois não queria presumir nada do questionador. Além disso, antes de tentar fazer o launchd plist funcionar, o script precisa ser capaz de executar a partir da CLI.
afragen

1

É executável?

chmod 700 ~/script.sh

no terminal. Além disso, eu não usaria $ HOME ou ~, mas o caminho real para o arquivo.

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

Qual o motivo do voto negativo?
TJ Luoma

1

Se o seu script for um agente de usuário (e, portanto, localizado na biblioteca da pasta base), launchdo diretório de trabalho atual é a pasta base. UNIX refere-se ao diretório inicial com um ponto no caminho.

Então, basicamente, use em ./script.shvez de ~/script.sh. ;-)


3
Não, o diretório de trabalho do launchd é /, na verdade , não '~'.
Tyilo 7/03/13

@ Tyilo Eu não tenho certeza do que você quer dizer. Se você quer dizer "o diretório de trabalho do launchd é a raiz, em todos os casos, mesmo no modo de usuário", forneça uma referência. Se você quer dizer "launchd usa uma barra em vez de um til", leia minha postagem novamente. A propósito, tenho vários scripts agendados no launchd e eles seguem o comportamento que eu descrevo. ;-)
Constantino Tsarouhas

1
@RandyMarch Fiz um agente de lançamento em ~/Library/LaunchAgentscom os argumentos: sh, -c, echo $HOME > /Users/Tyilo/launchd_home.txt. Quando executou o arquivo /Users/Tyilo/launchd_home.txtcontido /, não /Users/Tyilo.
Tyilo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.