it-swarm.com.de

Wie simuliert man die Umgebung, mit der cron ein Skript ausführt?

Normalerweise habe ich einige Probleme mit der Art und Weise, wie cron Skripte ausführt, da sie normalerweise keine Umgebungseinstellungen haben. Gibt es eine Möglichkeit, bash (?) Auf die gleiche Weise aufzurufen, wie cron, damit ich Skripts testen kann, bevor sie installiert werden?

224
Jorge Vargas

Fügen Sie dies Ihrem cron hinzu:

30 08 * * * env > ~/cronenv

Nachdem es läuft, tun Sie dies:

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

Dies setzt voraus, dass Ihr cron/bin/sh ausführt, was unabhängig von der Standard-Shell des Benutzers der Standard ist.

349
mmccoo

Cron bietet standardmäßig nur diese Umgebung:

  • HOME Home-Verzeichnis des Benutzers
  • LOGNAME Benutzeranmeldung
  • PATH=/usr/bin:/usr/sbin
  • Shell=/usr/bin/sh

Wenn Sie mehr benötigen, können Sie ein Skript verwenden, in dem Sie Ihre Umgebung vor der Planungstabelle in der Crontab definieren.

60
gregseth

Einige Ansätze:

  1. cron env exportieren und beziehen:

    Hinzufügen

    * * * * * env > ~/cronenv
    

    zu Ihrem Crontab, lassen Sie ihn einmal laufen, schalten Sie ihn wieder aus und dann los

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

    Und Sie befinden sich jetzt in einer sh-Sitzung, die die cron-Umgebung hat

  2. Bringen Sie Ihre Umgebung zu cron

    Sie könnten die obige Übung überspringen und vor Ihrem Cron-Job einen . ~/.profile ausführen, z. 

    * * * * * . ~/.profile; your_command
    
  3. Bildschirm verwenden

    Die obigen beiden Lösungen schlagen immer noch fehl, indem sie eine Umgebung bereitstellen, die mit einer laufenden X-Sitzung verbunden ist, mit Zugriff auf dbus usw. Zum Beispiel funktioniert nmcli (Network Manager) unter Ubuntu in zwei Vorgehensweisen, schlägt jedoch in cron fehl.

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

    Fügen Sie die obere Zeile zu cron hinzu, lassen Sie es einmal laufen und schalten Sie es wieder aus. Stellen Sie eine Verbindung zu Ihrer Bildschirmsitzung her (Bildschirm -r). Wenn Sie prüfen, ob die Bildschirmsitzung erstellt wurde (mit ps), beachten Sie, dass sie manchmal in Großbuchstaben sind (z. B. ps | grep SCREEN).

    Jetzt wird auch nmcli und ähnliches fehlschlagen.

42
Cookie

Du kannst rennen:

env - your_command arguments

Dadurch wird Ihr_Befehl in einer leeren Umgebung ausgeführt.

21
dimba

Abhängig von der Shell des Kontos

Sudo su
env -i /bin/sh

oder

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

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

13
tcurdt

Antwort sechs Jahre später: Das Problem der Umgebungskonflikte ist eines der Probleme, die von systemd "Zeitgebern" als Cronersatz gelöst werden. Unabhängig davon, ob Sie den systemd "Service" über die CLI oder über cron ausführen, erhält er genau dieselbe Umgebung, wodurch das Problem der Umgebungskonflikte vermieden wird.

Das häufigste Problem, das dazu führt, dass cron-Jobs fehlschlagen, wenn sie manuell übergeben werden, ist der von cron festgelegte restriktive Standardcode $PATH, der auf Ubuntu 16.04 lautet:

"/usr/bin:/bin"

Im Gegensatz dazu ist der von systemd unter Ubuntu 16.04 festgelegte Standardcode $PATH:

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

Daher besteht bereits eine bessere Chance, dass ein systemd-Timer ohne weiteres eine Binärdatei findet.

Der Nachteil bei systemd-Timern ist, dass sie etwas mehr Zeit haben, um sie einzurichten. Zuerst erstellen Sie eine "Service" -Datei, um zu definieren, was Sie ausführen möchten, und eine "Timer" -Datei, um den Zeitplan zu definieren, auf dem sie ausgeführt werden soll, und schließlich den Timer zu aktivieren, um ihn zu aktivieren. 

12
Mark Stosberg

Erstellen Sie einen Cron-Job, der env ausführt und stdout in eine Datei umleitet. Verwenden Sie die Datei neben "env -", um dieselbe Umgebung wie ein Cron-Job zu erstellen.

10
Jens Carlberg

Vergiss nicht, dass crons Elternteil init ist und Programme ohne steuerndes Terminal ausführt. Sie können das mit einem Tool wie diesem simulieren:

http://libslack.org/daemon/

3
Randy Proctor

Standardmäßig führt cron die Jobs nach den Vorstellungen Ihres Systems von sh aus. Dies kann die tatsächliche Bourne-Shell oder dash, ash, ksh oder bash (oder eine andere) sein, die mit sh verknüpft ist (und als Ergebnis im POSIX-Modus ausgeführt wird).

Das Beste, was Sie tun können, ist sicherzustellen, dass Ihre Skripts das bieten, was sie brauchen, und davon auszugehen, dass nichts für sie bereitgestellt wird. Daher sollten Sie vollständige Verzeichnisspezifikationen verwenden und Umgebungsvariablen wie $PATH selbst festlegen.

2

Eine andere einfache Möglichkeit, die ich gefunden habe (aber möglicherweise fehleranfällig ist, ich teste immer noch), besteht darin, die Profildateien Ihres Benutzers vor Ihrem Befehl zu finden.

/Etc/cron.d/ Skript bearbeiten:

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

Würde sich in:

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

Dirty, aber es hat die Arbeit für mich erledigt. Gibt es eine Möglichkeit, ein Login zu simulieren? Nur ein Befehl, den Sie ausführen könnten? bash --login hat nicht funktioniert. Es klingt so, als wäre dies der bessere Weg.

EDIT: Dies scheint eine solide Lösung zu sein: 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

Antwort https://stackoverflow.com/a/2546509/5593430 zeigt, wie Sie die cron-Umgebung beziehen und für Ihr Skript verwenden. Beachten Sie jedoch, dass sich die Umgebung je nach verwendeter Crontab-Datei unterscheiden kann. Ich habe drei verschiedene cron-Einträge erstellt, um die Umgebung über env > log zu speichern. Dies sind die Ergebnisse auf einem Amazon Linux 4.4.35-33.55.amzn1.x86_64.

1. Globales/etc/crontab mit root-Benutzer

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. Benutzer crontab von 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. Skript 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

Am wichtigsten sind jedoch PATH, PWD und HOME. Stellen Sie sicher, dass Sie diese in Ihren cron-Skripts festlegen, um sich auf eine stabile Umgebung zu verlassen.

0
Maikel