Ich habe einige Befehle, sie arbeiten unter Bash, aber nicht als Cronjob. Um zu sehen, was das Problem verursacht, speichere ich die Ausgabe in einer Datei, hier mein Beispiel:
51 * * * * source ~/.rvm/scripts/rvm >> stack.log 2>&1
Der Inhalt der Protokolldatei lautet:
/bin/sh: 1: source: not found
Das heißt, Cron verwendet sh
Insead von bash
. Ich habe versucht, es zu ändern in /etc/crontab
:
SHELL=/bin/bash
Das funktioniert aber nicht. Ich habe in die /etc/passwd
und hier sehe ich, dass der Dämon sh
als Standard-Shell verwendet. Beide root
und pi
haben bash
als Standard-Shell.
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
pi:x:1000:1000:,,,:/home/pi:/bin/bash
Was soll ich tun, um die Standard-Shell für cron zu ändern? Ich würde nicht /bin/bash
für den Daemon-Benutzer /etc/passwd
einstellen in ... imho das ist keine gute Idee.
bearbeiten :
ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 30 2012 /bin/sh -> dash
hier der Inhalt der /etc/crontab
:
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
source
in crons Umgebung? Einfach das laufen zu lassen~/.rvm/scripts/rvm
funktioniert nicht? Und Sie können Probleme mit der Verwendung von ~ in Nicht-Bash-Umgebungen haben.Antworten:
Die verwendete Shell ist
dash
; Eine POSIX-kompatible Shell, die viel kleiner und stabiler als istbash
.Man könnte argumentieren, dass Sie
cron
Jobs schreiben sollten , um POSIX-kompatibel zu sein. Alternativ können Sie versuchen, Ihre Logik in ein Skript zu kapseln und den Shebang voranzustellenquelle
bash
an anderer Stelle aufbewahrt werden. Wer das machen würde, weiß ich nicht!/etc/crontab
bitte dein gesamtes einfügen ?source
ein eingebautes, was keinen Sinn macht, alleine zu laufen.Die meisten dieser Fälle (in denen das Skript in der Shell, aber nicht in Cron funktioniert) sind auf Umgebungsvariablen zurückzuführen, die sich im Skript unterscheiden. In vielen Fällen sind die Probleme
PATH
variabel. Sie können vollständige Pfade zu allen ausführbaren Dateien verwenden, die Sie im Skript ausführen, oderPATH
in der ersten Zeile Ihres Skripts ändern .Um solche Probleme zu verfolgen, können Sie zunächst Umgebungsvariablen sichern, die für Ihr Skript verfügbar sind, indem Sie den folgenden
env
Befehl verwenden: / usr / bin / env> /tmp/env.txtquelle
PATH
das bereits erwähnte. Versuchen Sie es/usr/bin/env
stattdessen. Oder verwenden Siewhich env
, um zu überprüfen, welchen Pfad Sie vollständig verwendenenv
müssen.Sind Sie sicher, dass
sourcing
Ihr Skript genau dascron
ist, was Sie tun möchten und, was noch wichtiger ist, notwendig ist? Ich denke, dass es fast immer eine schlechte Idee ist.cron
Versuchen Sie außerdem, beim Bearbeiten (sowie bei anderen Tools, die möglicherweise von anderen Benutzern und / oder anderen Shells gestartet werden können) Schritt für Schritt vorzugehen. Zum Beispiel können Sie Ihre Umgebung folgendermaßen testen:oder auch:
So können Sie Beweise für Ihre Umgebung usw. haben.
Um Ihre Frage zu beantworten, würde ich die Shell für nicht ändern
cron
. Ich würde es einfach aufrufenbash
und dannbash
Ihre Skripte aufrufen lassen .quelle
cron
. Wie gesagt, ich würde es nicht ändern. Sie einfach Ihr Skript aufrufen durchbash
mitbash -c "yourscript"
und alles sollte in Ordnung sein (nicht Ihr Skript beziehen, werden Sie wahrscheinlich brauchen sie nicht!)Also ... ich habe zwei Lösungen für mein Problem:
Wrapper-Skript über den Bash-Befehl, den ich gerade als Cronjob aufrufe. Das Problem hier - für jeden Cronjob brauche ich einen Wrapper, und das ist nicht die beste Lösung für mich.
Ich habe versucht, ein Ruby-Skript als Cronjob zu bezeichnen. Das funktioniert nicht, also dachte ich, ich muss 'rvm use 1.9.3' aufrufen und dafür muss ich zuerst 'source ~ / .rvm / scripts / rvm' aufrufen. Und hier war mein Fehler. In meiner Bash-Instanz habe ich einen Pfad zu Rubin, aber nicht als Cron. Nachdem ich das behoben habe, funktioniert alles gut und ich kann meine Ruby-Skripte als Cronjob ausführen.
Alex Chamberlain hat mir sehr geholfen und mir die wichtigsten Hinweise gegeben. Vielen Dank für die Hilfe !!!
quelle