O executável Python Script / Unix é executado no terminal, falha como trabalho Cron / Launchd

1

Estou tentando configurar o launchd para acionar um executável de script / unix python (ou seja, script python com shebang line ). Quando carrego o arquivo .plist (abaixo), launchctl mostra um status 127 significando "O serviço especificado não foi enviado com o sistema operacional". No entanto, quando eu copio e colo o valor que eu digitei para 'programa' no arquivo .plist no terminal mac ele roda bem.

Eu redirecionei stdout / stderr para o terminal (via .plist) e ele retorna a mensagem

$ env: python3: No such file or directory

Se eu substituir o valor de Program no plist por um simples script de lote 'hello world', ele funciona bem.

Por que o programa python (urlwatch) roda bem no terminal, mas retorna um erro quando chamado via launchd? Como faço para corrigir isso?

Arquivo Plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" \
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>local.careersWatch3</string>
        <key>Program</key>
        <string>/Users/justinmichael/Documents/urlwatch-master/urlwatch</string>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardOutPath</key>
        <string>/dev/ttys000</string>
        <key>StandardErrorPath</key>
        <string>/dev/ttys000</string>
    </dict>
</plist>

Eu, eventualmente, quero executar o script em horários determinados, mas por enquanto estou usando RunAtLoad = true para fins de teste até que eu consiga fazê-lo funcionar.

Carregando no launchd e na saída:

$ launchctl load  ~/Library/LaunchAgents/local.careerswatch3.plist
$ env: python3: No such file or directory

Ligue para verificar o status do agente e da saída:

$ launchctl list | grep local.careersWatch3
-   127 local.careersWatch3

Pesquisando o significado do código '127' no terminal:

$ launchctl error 127
127: The specified service did not ship with the operating system
    
por JMikes 11.02.2018 / 22:49

1 resposta

1

O problema era com as variáveis de ambiente, especificamente que o $ PATH é diferente para tarefas executadas por programas cron vs chamados por mim no terminal como um usuário logado. Chamar echo $PATH em um cron job e verificar se ele inclui o diretório do interpretador python pode ajudar a confirmar que esse é o problema.

Duas soluções:

1) Rápido e sujo

Encontre onde o interpretador Python está instalado e altere a linha shebang na parte superior do script unix executable / python para chamá-lo diretamente. ou seja,

#!/usr/bin/env python3

torna-se

#!/usr/local/bin/python3

Aqui, não importa se o interpretador python está no caminho ou não, porque sua localização é dada explicitamente. A desvantagem é que sua localização agora é codificada e se você mover o script para um computador diferente, o script pode não funcionar, nem no cron nem quando executado no terminal, se o python tiver sido instalado em um local diferente.

2) Menos rápido, menos sujo

Escreva um script de shell que adicione o local do interpretador python ao caminho, caso ainda não esteja lá (conforme this pergunta SuperUser) e, em seguida, chama o script python. Desta forma, o script não foi alterado e não será quebrado acidentalmente, movendo-o para um computador em que o Python está instalado em um diretório diferente.

#!/bin/bash
# directory python is found in
dir="usr/local/bin"
#add to path if not there
if [ -d "$dir" ] && [[ ":$PATH:" != *":$dir:"* ]]; then
        PATH="${PATH:+"$PATH:"}$dir"
fi
#Run program
/path/to/program/program_name

Certifique-se de tornar o script executável via chmod +x /path/to/script/script.sh

    
por 26.02.2018 / 21:54