risposta-alla-domanda-sullo-sviluppo-web-bd.com

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?

224
Jorge Vargas

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.

349
mmccoo

Cron fornisce solo questo ambiente per impostazione predefinita:

  • HOME home directory dell'utente
  • LOGNAME login dell'utente
  • 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.

60
gregseth

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

    Puoi saltare sopra l'esercizio e basta fare un . ~/.profile di fronte 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, disattivala. Collegati alla sessione dello schermo (schermo -r). Se stai verificando che la sessione dello schermo è stata creata (con ps), tieni presente che a volte sono in maiuscolo (ad es. ps | grep SCREEN)

    Adesso anche nmcli e simili falliranno.

42
Cookie

Puoi eseguire:

env - your_command arguments

Questo eseguirà your_command con un ambiente vuoto.

21
dimba

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

13
tcurdt

Risposta a sei anni di distanza: il problema di disallineamento dell'ambiente è uno dei problemi risolti da systemd "timer" come sostituzione di cron. Sia che si esegua il "servizio" systemd dalla CLI o tramite cron, esso riceve esattamente lo stesso ambiente, evitando il problema di disallineamento dell'ambiente.

Il problema più comune per cui i processi cron falliscono quando passano manualmente è il default $PATH limitato impostato da cron, che è presente su Ubuntu 16.04:

"/usr/bin:/bin"

Al contrario, il default $PATH 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 attivarlo. 

12
Mark Stosberg

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

10
Jens Carlberg

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/

3
Randy Proctor

Per default, cron esegue i suoi lavori usando qualunque sia l'idea del tuo sistema di sh. Questa potrebbe essere la Bourne Shell effettiva o dash, ash, ksh o bash (o un'altra) symlinked a sh (e di conseguenza l'esecuzione in modalità POSIX).

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

2

Un altro modo semplice che ho trovato (ma potrebbe essere soggetto 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 trasformerebbe 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
1
four43

Rispondi https://stackoverflow.com/a/2546509/5593430 mostra come ottenere l'ambiente cron e usarlo per il tuo script. Ma 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.

0
Maikel