Cron in derselben Umgebung ausführen lassen, die ich beim SSH-Login erhalte

Cron in derselben Umgebung ausführen lassen, die ich beim SSH-Login erhalte

Ich habe ein Skript, das einwandfrei läuft, wenn ich per SSH auf meine Ubuntu EC2-Instanz zugreife und es ausführe (als Benutzer ubuntu).

Ich möchte, dass dies beim Booten des Servers geschieht, daher habe ich es wie folgt zu Cron hinzugefügt:

@reboot sleep 10 && /home/ubuntu/start.sh

Wenn es jedoch mit Cron ausgeführt wird, PATHist es nicht dasselbe und einige Befehle schlagen fehl, weil die Binärdateien nicht geladen werden:

$ echo $PATH
/home/ubuntu/.nvm/versions/node/v4.2.6/bin:/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

# in start.sh
echo "path $PATH" >> start.logs
# will log 'path /usr/bin:/bin'

source /home/ubuntu/.bashrcIch habe versucht, es in mein start.shSkript einzufügen, da ich glaube, dass es dort PATHzumindest teilweise erstellt wird, aber das scheint nicht viel zu ändern:

# in start.sh
source /home/ubuntu/.bashrc
echo "path $PATH" >> start.logs
# will still log 'path /usr/bin:/bin'

Ich habe auch überprüft, dass Cron als ubuntuund nicht ausgeführt wird root, was der Fall zu sein scheint, da ich die Cron-Jobs bearbeitet habe, die als angemeldet sindubuntu

Gibt es eine einfache Möglichkeit, Cron in derselben Umgebung auszuführen, die ich nach der Anmeldung bei meinem Server per SSH erhalte?

Antwort1

Normalerweise sollten Umgebungsvariablen in definiert werden ~/.profile, oder ~/.bash_profilewenn diese Datei existiert, ist Ihre Login-Shell Bash. Laden Sie diese Datei also vom Cron-Job.

@reboot . ~/.profile; sleep 10 && /home/ubuntu/start.sh

~/.bashrcist nur für interaktive Anpassungen gedacht, Sie sollten es also nicht nicht-interaktiv laden, und normalerweise funktioniert es sowieso nicht. Wenn Sie Umgebungsvariablendefinitionen in haben .bashrc, beheben Sie zuerst dieses Durcheinander.

Ein weiterer Ort zum Festlegen von Umgebungsvariablen ist ~/.pam_environment, wenn Sie der Variable einen konstanten Wert zuweisen möchten (Sie können in dieser Datei keine Shell-Befehle ausführen).

SehenWas ist die beste Distributions-/Shell-unabhängige Methode zum Festlegen von Umgebungsvariablen?,Unterschied zwischen Login-Shell und Nicht-Login-Shell?UndGibt es eine „.bashrc“-Äquivalentdatei, die von allen Shells gelesen wird?für weitere Informationen zu Shell-Startdateien.

Antwort2

cron wird normalerweise mit sh und nicht mit bash ausgeführt, diese haben unterschiedliche Profile.

Versuchen Sie, den einzelnen Cron unter Bash auszuführen. Wenn Sie über mehrere benutzerdefinierte Umgebungsvariablen verfügen, können Sie im Cron immer „env>/file“, „source /file“ verwenden.

Antwort3

Ich habe mein Problem wie folgt gelöst:

  • run $ crontab -eund vor allen anderen Zeilen hinzufügen. SHELL=/bin/bashDadurch wird cron gezwungen, bash zu verwenden. Es gibtAlternativenwenn Sie das nur für einen Befehl tun möchten
  • mein .bashrc, das ist die Standardeinstellung, die Sie auf einer AWS EC2 Ubuntu-Instanz erhalten, enthielt diese Zeilen:

.

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Dies source /home/ubuntu/.bashrcwürde im Cron-Job nichts bewirken. Es scheint einen Zweck zu erfüllen, also habe ich es nicht vollständig entfernt, sondern durch Folgendes ersetzt:

# If not running interactively, don't do anything
if [ -z ${RUN_BASHRC+x} ]; then
  echo "might return";
else
  case $- in
      *i*) ;;
        *) return;;
  esac
fi

Dadurch konnte ich ein Flag setzen, um diese vorzeitige Rückgabe zu umgehen.

  • Aus irgendeinem Grund PATHwurde das Update immer noch nicht korrekt durchgeführt. Ich konnte das Problem folgendermaßen beheben:

.

ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH

Ich bin nicht 100 % sicher, was das bewirkt :), aber am Ende habe ich dasselbe Ergebnis, das PATHich bei der Anmeldung per SSH hätte.

So endlich:

crontab:

SHELL=/bin/bash
@reboot RUN_BASHRC=1 /home/ubuntu/startup.sh >> /home/ubuntu/cron-startup.logs

~/.bashrc: der obige Ersatz

~/start.sh:

#!/bin/bash
ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH
...

verwandte Informationen