Shutdown Script in macOS / RAM Disk Backup

0

Sto tentando di creare uno script di arresto in macOS (10.11), ovvero uno script che viene eseguito allo spegnimento, non uno script che si chiude nel Mac. Il sistema linux "rc" non è presente in macOS.

Ho cercato e cercato una soluzione, e questo è l'unico che sono riuscito a trovare. Viene avviato all'avvio con launchd e le funzioni di avvio e arresto vengono eseguite quando dovrebbero:

#!/bin/bash

function startup()
    {
    ## commands to create and fill ram disk

    tail -f /dev/null &
    wait $!
    }

function shutdown()
    {
    ## commands to backup contents of ramdisk

    exit 0
    }

trap shutdown SIGTERM

startup;

Come ho detto, entrambe le funzioni startup () e shutdown () vengono eseguite quando previsto. Il problema si trova all'interno dei comandi della funzione di spegnimento. È uno script piuttosto semplice, copia semplicemente il contenuto del disco ram in una cartella sul disco rigido:

function backup_ramdisk()
    {
    ## empty ram disk backup folder
    rm -R -f /webfolder-backup/*

    ## copy contents of the ramdisk to the ramdisk backup
    cp -R /Volumes/webfolder/ /webfolder-backup/

    ## make me the owner
    chown -R me /webfolder-backup/
    chmod -R 777 /webfolder-backup/ 

    exit 0
    }

Lo script vero e proprio è caricato con extra che registrano roba e posso confermare che l'intero script viene eseguito. Ma quello che succede è che la riga cp fallisce. A volte fallisce completamente e la cartella di backup è vuota. Ma più spesso, ottiene parte della struttura del disco RAM e interrompe la copia dei file intorno (ma non esattamente) nello stesso punto.

Spesso genera l'errore cp: /Volumes/webfolder/: No such file or directory anche se ha già copiato un centinaio di elementi da quella cartella. Mi viene da pensare che il comando shutdown stia smontando il disco RAM prima che il mio script abbia il tempo di terminare il backup. Tieni presente che, trattandosi di un disco RAM, bastano un paio di secondi per copiare tutti i file da esso. Ma sembra che non sia abbastanza. Se ci fosse un modo per mettere in pausa il processo di spegnimento mentre il mio script è in esecuzione, quindi procedere, sarebbe l'ideale! O forse un approccio migliore a questo interamente?

    
posta l008com 08.03.2018 - 01:55
fonte

1 risposta

1

Per quanto riguarda il confronto con Linux: Mac OS X aveva effettivamente il sistema "rc", lo sai da Linux (in realtà è chiamato sistema SysV init). Nel 2005 questo sistema è stato abbandonato con OS X Lion, e invece è stato introdotto il più moderno launchd system, che ha portato, tra le altre cose, a stivali molto più veloci.

Su Linux lo stesso cambiamento è avvenuto, comunque più tardi che su macOS. Oggigiorno le distribuzioni Linux usano comunemente systemd, upstart o simili "moderni" take su un sistema init.

Per quanto riguarda la tua soluzione - è davvero un hack, e non ha funzionato nel modo giusto. Questo è il motivo per cui hai problemi. Stai intercettando sia SIGTERM che SIGKILL - questo è contro i consigli, ed è la causa del messaggio di errore "Nessun file o directory".

Fondamentalmente ciò che accade su shutdown (questo è completamente simile a Linux) è che ogni processo viene inviato a SIGTERM per far sapere che dovrebbe terminare. Il processo quindi ha solo un tempo molto breve per chiudere (cioè entro pochi secondi) - altrimenti il sistema invia il segnale SIGKILL per uccidere realmente il processo se non risponde.

Nel tuo caso quando la copia impiega un po 'troppo tempo, intrappoli i segnali entrambi e eseguirai la tua funzione shutdown () due volte.

Non hai incluso la tua configurazione di launchd (vale a dire probabilmente un plist daemon), ma devi fare attenzione ad avere dipendenze e ordini configurati qui per far funzionare il tuo hack. Altrimenti si rischia di smontare il disco RAM prima che venga chiamato lo shutdown (che probabilmente è ciò che accade quando si esegue lo shutdown la seconda volta a causa del segnale SIGKILL.

Per quanto ricordo il file /etc/rc.shutdown.local è ancora un metodo valido per eseguire programmi all'arresto. Questo è di gran lunga il modo più semplice per farlo.

Crea semplicemente il file /etc/rc.shutdown.local e rendilo eseguibile. Dovrebbe iniziare con uno shebang come il tuo script corrente, ma deve solo contenere i comandi che usi per copiare i file sul tuo backup.

Se vuoi farlo correttamente con launchd puoi modificare il tuo hack per gestire correttamente i segnali, e poi usare le funzioni xpc_transaction_begin / end per far sapere al sistema che il tuo programma sta facendo un lavoro utile, e lo shutdown dovrebbe essere ritardato fino terminato - o in alternativa utilizzare la funzionalità di trigger evento in launchd.

Ti consiglio di provare prima /etc/rc.shutdown.local. È deprecato, ma per quanto ricordo ancora funzionante.

Un piccolo avvertimento è probabilmente anche una buona idea per te. Ricorda che non sarai mai garantito che il tuo programma di spegnimento verrà eseguito. Non è quindi una buona idea conservare cose che non vuoi perdere in un disco RAM del genere. Una singola interruzione di corrente e i tuoi dati sono persi. Utilizza invece sincronizzazioni di dati frequenti o simili per garantire che i dati vengano periodicamente sottoposti a backup su storage permanente.

Per quanto riguarda la tua richiesta se esiste un approccio migliore - allora la risposta è "molto probabilmente sì". L'idea di copiare una cartella Web in dischi RAM sembra un po 'storica e datata. Non abbiamo informazioni su ciò che stai facendo con quella cartella web, ma se stai solo servendo i siti web e vuoi che sia veloce usando un disco RAM - questo è l'approccio sbagliato. È molto meglio usare la funzionalità di cfsing di vfs integrata di macOS (simile a qualsiasi altro sistema operativo moderno, come Linux).

    
risposta data 08.03.2018 - 10:02
fonte

Leggi altre domande sui tag