Come simulare l’ambiente con cui viene eseguito uno script?

Normalmente ho diversi problemi con il modo in cui cron esegue gli script poiché normalmente non hanno la mia configurazione dell’ambiente. C’è un modo per invocare bash (?) Nello stesso modo in cui cron fa così posso testare gli script prima di installarli?

Aggiungi questo al tuo cron:

30 08 * * * env > ~/cronenv 

Dopo l’esecuzione, fai questo:

 env - `cat ~/cronenv` /bin/sh 

Ciò presuppone che il tuo cron esegua / bin / sh, che è l’impostazione predefinita indipendentemente dalla shell predefinita dell’utente.

Cron fornisce solo questo ambiente per impostazione predefinita:

  • Directory home dell’utente HOME
  • LOGNAME dell’utente LOGNAME
  • PATH=/usr/bin:/usr/sbin
  • SHELL=/usr/bin/sh

Se hai bisogno di più puoi creare uno script in cui definire il tuo ambiente prima della tabella di pianificazione in crontab.

Paio di approcci:

  1. Esporta cron env e cercalo:

    Inserisci

     * * * * * env > ~/cronenv 

    al tuo crontab, fallo correre, spegnilo e poi corri

     env - `cat ~/cronenv` /bin/sh 

    E ora sei all’interno di una sessione sh che ha l’ambiente di cron

  2. Porta il tuo ambiente a cron

    Si può saltare sopra l’esercizio e basta fare a . ~/.profile . ~/.profile davanti al tuo cron job, ad es

     * * * * * . ~/.profile; your_command 
  3. Usa schermo

    Al di sopra di due soluzioni ancora non riescono in quanto forniscono un ambiente connesso a una sessione X in esecuzione, con accesso a dbus ecc. Ad esempio, su Ubuntu, nmcli (Network Manager) funzionerà in oltre due approcci, ma fallisce ancora in cron.

     * * * * * /usr/bin/screen -dm 

    Aggiungi la riga precedente a cron, lasciala eseguire una volta, distriggersla. Collegati alla sessione dello schermo (schermo -r). Se stai verificando che la sessione dello schermo è stata creata (con ps ), ps presente che a volte sono in maiuscolo (ad esempio ps | grep SCREEN )

    Adesso anche nmcli e simili falliranno.

Puoi eseguire:

 env - your_command arguments 

Questo eseguirà your_command con un ambiente vuoto.

A seconda della shell dell’account

 sudo su env -i /bin/sh 

o

 sudo su env -i /bin/bash --noprofile --norc 

Da http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html

Risposta sei anni dopo: il problema di disallineamento dell’ambiente è uno dei problemi risolti dai “timer” systemd come sostituzione di cron. Sia che si esegua il “servizio” systemd dalla CLI o tramite cron, riceve esattamente lo stesso ambiente, evitando il problema di disallineamento dell’ambiente.

Il problema più comune in cui i job cron falliscono quando passano manualmente è il $PATH predefinito impostato da cron, che è presente su Ubuntu 16.04:

 "/usr/bin:/bin" 

Al contrario, il $PATH predefinito impostato da systemd su Ubuntu 16.04 è:

 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 

Quindi c’è già una migliore possibilità che un timer systemd trovi un binario senza ulteriori problemi.

Il lato negativo con i timer di sistema, c’è un po ‘più tempo per configurarli. Per prima cosa create un file “servizio” per definire cosa volete eseguire e un file “timer” per definire la pianificazione per eseguirlo e infine “abilitare” il timer per triggersrlo.

Crea un processo cron che esegue env e reindirizza lo stdout in un file. Utilizzare il file accanto a “env -” per creare lo stesso ambiente di un processo cron.

Non dimenticare che dal momento che il genitore di cron è init, esegue programmi senza un terminale di controllo. Puoi simularlo con uno strumento come questo:

http://libslack.org/daemon/

Di default, cron esegue i suoi lavori usando qualunque sia l’idea del sistema di sh . Questa potrebbe essere la shell Bourne effettiva o dash , ash , ksh o bash (o un’altra) collegata a sh (e come risultato in esecuzione in modalità POSIX).

La cosa migliore da fare è assicurarsi che gli script abbiano ciò di cui hanno bisogno e che non venga fornito nulla per loro. Pertanto, è necessario utilizzare le specifiche di directory complete e impostare variabili di ambiente come $PATH .

Un altro modo semplice che ho trovato (ma potrebbe essere sobject a errori, sto ancora testando) è di cercare i file del profilo dell’utente prima del comando.

Modifica di uno script /etc/cron.d/:

 * * * * * user1 comand-that-needs-env-vars 

Si trasformsrebbe in:

 * * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars 

Sporco, ma ha fatto il lavoro per me. C’è un modo per simulare un login? Solo un comando che potresti eseguire? bash --login non ha funzionato. Sembra che sarebbe il modo migliore per andare comunque.

EDIT: Questa sembra essere una soluzione solida: http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/

 * * * * * root su --session-command="comand-that-needs-env-vars" user1 -l 

Risposta https://stackoverflow.com/a/2546509/5593430 mostra come ottenere l’ambiente cron e usarlo per il tuo script. Tuttavia, tieni presente che l’ambiente può variare in base al file crontab che utilizzi. Ho creato tre diverse voci di cron per salvare l’ambiente tramite env > log . Questi sono i risultati su Amazon Linux 4.4.35-33.55.amzn1.x86_64.

1. Globale / etc / crontab con utente root

 MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=1 HOME=/ LOGNAME=root _=/bin/env 

2. Crontab utente di root ( crontab -e )

 SHELL=/bin/sh USER=root PATH=/usr/bin:/bin PWD=/root LANG=en_US.UTF-8 SHLVL=1 HOME=/root LOGNAME=root _=/usr/bin/env 

3. Script in /etc/cron.hourly/

 MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin _=/bin/env PWD=/ LANG=en_US.UTF-8 SHLVL=3 HOME=/ LOGNAME=root 

Soprattutto PATH , PWD e HOME differiscono. Assicurati di impostarli negli script di cron per fare affidamento su un ambiente stabile.

Non credo che ci sia; l’unico modo che conosco per testare un cron job è impostarlo per eseguire un minuto o due in futuro e quindi attendere.