Come ri-span uno script launchd simile a cron in caso di errore di script?

1

Ho uno script launchd simile a cron ( StartCalendarInterval ) che esegue il backup di alcuni dati del sito web una volta al giorno:

<?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.example.backup</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Volumes/Example/backup.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>2</integer>
            <key>Minute</key>
            <integer>15</integer>
        </dict>
    </array>
    <key>StandardErrorPath</key>
    <string>/var/log/com.example/backup_error</string>
    <key>StandardOutPath</key>
    <string>/var/log/com.example/backup_output</string>
</dict>
</plist>

In rari casi potrebbe andare storto quando Internet non è disponibile. Lo script backup.sh imposta quindi un codice di errore corretto maggiore di 0.

Ora vorrei che lo script venga riavviato automaticamente un'ora dopo un errore. E ancora e ancora fino a quando non ci sono errori. Ma non dopo 24 ore per evitare che due istanze dello script vengano eseguite contemporaneamente.

Credo che ciò sia possibile con ThrottleInterval e SuccessfulExit . Il mio problema è che SuccessfulExit è collegato a KeepAlive . Non voglio che lo script venga eseguito sempre, ma solo una volta al giorno tramite StartCalendarInterval .

Il mio compito è direttamente eseguibile con launchd? O dovrei semplicemente aggiungere wait 1 hour and try again after error al mio script? Lo script richiederebbe sempre risorse quando impostato in questo modo. Vorrei evitare questo.

    
posta Haru 13.07.2015 - 01:55
fonte

1 risposta

1

Sembra che possa essere fatto parzialmente. Fondamentalmente il problema era che KeepAlive in combinazione con SuccessfulExit implicava RunAtLoad (il programma è stato avviato proprio all'inizio e non al StartCalendarIntervall specificato.) Impostazione del parametro aggiuntivo AfterInitialDemand (che non è documentato) cambierà questo comportamento e il programma verrà lanciato per la prima volta all'ora di calendario specificata:

<?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.example.backup</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Volumes/Example/backup.sh</string>
    </array>

    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>2</integer>
            <key>Minute</key>
            <integer>15</integer>
        </dict>
    </array>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
        <key>AfterInitialDemand</key>
        <true/>
    </dict>
    <key>ThrottleInterval</key>
    <integer>3600</integer>

    <key>StandardErrorPath</key>
    <string>/var/log/com.example/backup_error</string>
    <key>StandardOutPath</key>
    <string>/var/log/com.example/backup_output</string>
</dict>
</plist>

L'unico problema è che se il programma / script fallisce allora ThrottleInterval sostituirà StartCalendarInterval , quindi a seconda del momento dell'errore e dell'intervallo impostato il programma / lo script non si avvierà esattamente al tempo di calendario specificato dopo un è trascorso il giorno (supponendo che non sia riuscito fino a quel momento) e potrebbe continuare in offset di tempo dispari (finché non ha esito positivo).

Ma per riassumere: il trucco è il AfterInitialDemand non documentato impostato su true .

    
risposta data 15.07.2015 - 23:46
fonte

Leggi altre domande sui tag