Gibt es eine Variable, die Cron beim Ausführen eines Programms setzt? Wenn das Skript von cron ausgeführt wird, möchte ich einige Teile überspringen. Andernfalls rufen Sie diese Teile auf.
Woher weiß ich, ob das Bash-Skript von cron gestartet wurde?
ps
?ps
es ziemlich schlecht dokumentiert ist (insbesondere die Linux-Version, die verschiedene Syntaxstile unterstützt) und die Manpage noch dichter und kryptischer ist als die meisten Tools. Ich vermute, die meisten Leute wissen nicht einmal, wie nützlich und vielseitig ein Werkzeug seinps
kann.Antworten:
Mir ist nicht bewusst, dass
cron
dies standardmäßig irgendetwas mit der Umgebung zu tun hat, was hier von Nutzen sein kann, aber es gibt ein paar Dinge, die Sie tun können, um den gewünschten Effekt zu erzielen.1) Machen Sie einen harten oder weichen Link auf die Skriptdatei, so dass zum Beispiel
myscript
undmyscript_via_cron
auf die gleiche Datei. Sie können dann den Wert$0
innerhalb des Skripts testen, wenn Sie bestimmte Teile des Codes bedingt ausführen oder weglassen möchten. Geben Sie den entsprechenden Namen in Ihre Crontab ein, und schon sind Sie fertig.2) Fügen Sie dem Skript eine Option hinzu, und legen Sie diese Option im Aufruf von crontab fest. Fügen Sie beispielsweise eine Option hinzu
-c
, die das Skript anweist, die entsprechenden Teile des Codes auszuführen oder wegzulassen, und fügen Sie-c
sie dem Befehlsnamen in Ihrer crontab hinzu.Und natürlich cron können beliebige Umgebungsvariablen gesetzt, so dass Sie nur eine Zeile wie setzen könnte
RUN_BY_CRON="TRUE"
in Ihre crontab, und prüfen Sie seinen Wert in Ihrem Skript.quelle
Skripte, die von cron ausgeführt werden, werden nicht in interaktiven Shells ausgeführt. Weder sind Startskripte. Die Unterscheidung besteht darin, dass interaktive Shells STDIN und STDOUT an ein tty angehängt haben.
Methode 1: Überprüfen Sie, ob
$-
dasi
Flag enthalten ist.i
ist auf interaktive Shells eingestellt.Methode 2: Prüfung
$PS1
ist leer.Referenz: http://techdoc.kvindesland.no/linux/gnubooks/bash/bashref_54.html
Methode 3: Testen Sie Ihre tty. Es ist nicht so zuverlässig, aber für einfache Cron-Jobs sollten Sie in Ordnung sein, da Cron einem Skript standardmäßig kein tty zuweist.
Denken Sie daran, dass Sie eine interaktive Shell mit erzwingen können
-i
, aber Sie wären sich wahrscheinlich bewusst, wenn Sie dies tun würden ...quelle
bash
ich Zugriff habe, hat $ -, genau wiedash
undksh
. Sogar die eingeschränkten Shells in Solaris haben es. Auf welcher Plattform möchten Sie es verwenden, wenn es nicht funktioniert? Wascase "$-" in *i*) echo true ;; *) echo false ;; esac
zeigt es dir?Holen Sie sich zuerst die PID von cron, dann die übergeordnete PID (PPID) des aktuellen Prozesses und vergleichen Sie sie:
Wenn Ihr Skript von einem anderen Prozess gestartet wird, der möglicherweise von cron gestartet wurde, können Sie die übergeordneten PIDs zurückgehen, bis Sie entweder $ CRONPID oder 1 (Init's PID) erhalten.
so etwas vielleicht (Untested-But-It-Might-Work <TM>):
Von Deian: Dies ist eine Version, die unter RedHat Linux getestet wurde
quelle
Wenn Ihre Skriptdatei von aufgerufen wird
cron
und eine Shell in der ersten Zeile enthält#!/bin/bash
, müssen Sie den übergeordneten Namen für Ihren Zweck suchen.1)
cron
wird zum angegebenen Zeitpunkt in Ihrem aufgerufencrontab
, Ausführen einer Shell 2) Shell führt Ihr Skript aus 3) Ihr Skript wird ausgeführtDie übergeordnete PID ist in bash als Variable verfügbar
$PPID
. Derps
Befehl zum Abrufen der übergeordneten PID der übergeordneten PID lautet:aber wir brauchen den Namen des Befehls, nicht die PID, also rufen wir an
Jetzt müssen wir nur noch das Ergebnis für "cron" testen
Jetzt können Sie überall in Ihrem Skript testen
Viel Glück!
quelle
P_COMMAND=$(basename -a $(ps h -o comm $PPPID))
Funktioniert unter FreeBSD oder Linux:
Sie können den Prozessbaum beliebig weit nach oben verschieben.
quelle
Eine generische Lösung für die Frage "Ist meine Ausgabe ein Terminal oder wird ein Skript ausgeführt?" Lautet:
quelle
Ein einfaches
echo $TERM | mail [email protected]
in cron hat mir gezeigt, dass cron sowohl unter Linux als auch unter AIX$TERM
auf 'dumm' gesetzt ist.Theoretisch gibt es vielleicht immer noch dumme Terminals, aber ich vermute, dass das für die meisten Gelegenheiten ausreichen sollte ...
quelle
Es gibt keine verbindliche Antwort, aber die Variablen prompt (
$PS1
) und terminal ($TERM
) sind hier ziemlich anständig. Einige Systeme werden so eingestellt, dassTERM=dumb
die meisten leer bleiben. Wir prüfen daher nur, ob:Der obige Code ersetzt das Wort "dumm", wenn es keinen Wert für gibt
$TERM
. Aus diesem Grund wird die Bedingung ausgelöst, wenn keine$TERM
oder$TERM
"dumm" eingestellt ist oder wenn die$PS1
Variable nicht leer ist.Ich habe dies unter Debian 9 (
TERM=
), CentOS 6.4 & 7.4 (TERM=dumb
) und FreeBSD 7.3 (TERM=
) getestet .quelle