wykonanie crontab nie ma takich samych zmiennych środowiskowych jak użytkownik wykonujący

20

Uruchomiłem zadanie crontab 0 2 */1 * * /aScript >aLog.log 2>&1jako użytkownik „root”, ale zauważyłem, że env różni się od env użytkownika „root” i dlatego mam inne zachowanie w czasie wykonywania moich skryptów.

Poprawką próbną było umieszczenie poleceń eksportu w plikach rc.d, ale wciąż się nie wyświetlało! W końcu umieszczam polecenia eksportu w samym aScript .

Moje pytanie brzmi: czy jest lepszy sposób na rozwiązanie tego problemu? i dlaczego brakuje env, mimo że pochodzi od tego samego użytkownika „root”? (Modyfikuję crontab, uruchamiając 'crontab -e' z katalogu głównego)

Bambus
źródło
8
Cron zawsze działa z prawie pustym środowiskiem. HOME, LOGNAME i SHELL są ustawione; i bardzo ograniczona ŚCIEŻKA. Jeśli nie chcesz samodzielnie ustawiać wszystkich zmiennych, być może będziesz mógł utworzyć sourceswój profil (bash).
cyberx86,
2
@ cyberx86: Dlaczego nie napisać tego jako odpowiedzi i uzyskać przedstawiciel?
user9517 obsługuje GoFundMonica
2
@Iain: przedstawiciel jest zawsze mile widziany - ale czasami wydaje się, że odpowiedź w jednym wierszu tak naprawdę nie zyskuje przedstawiciela. W pełni akceptuję, że zwięzła odpowiedź ma swoje miejsce, ale (być może niepoprawnie) używałem komentarzy jako „łatwego wyjścia”, gdy chciałem udzielić pomocy, ale nie napisałem pełnego, szczegółowego wyjaśnienia (była 1 w nocy). ..). Wezmę jednak twoją radę i rozwinę ją nieco i dodam jako odpowiedź.
cyberx86,
@ cyberx86: Lepiej mieć poprawną jedną linijkę niż niepoprawną lub nic.
user9517 obsługuje GoFundMonica

Odpowiedzi:

31

Cron zawsze działa z prawie pustym środowiskiem. HOME, LOGNAME i SHELL są ustawione; i bardzo ograniczona ŚCIEŻKA. Dlatego zaleca się stosowanie pełnych ścieżek do plików wykonywalnych i eksportowanie dowolnych zmiennych potrzebnych w skrypcie podczas korzystania z crona.

Istnieje kilka metod ustawiania zmiennych środowiskowych w cron, ale wszystkie sprowadzają się do ustawienia jej w skrypcie.

Podejście 1:

Ustaw każdą potrzebną zmienną ręcznie w skrypcie.

Podejście 2:

Źródło swojego profilu:

. $HOME/.bash_profile(lub . $HOME/.profile)

(Zazwyczaj przekonasz się, że powyższy plik będzie źródłem innych plików (np. ~ / .Bashrc -> / etc / bashrc -> /etc/profile.d/*) - jeśli nie, możesz również je zdobyć.)

Podejście 3:

Zapisz zmienne środowiskowe w pliku (uruchom jako pożądany użytkownik):

env > /path/to/my_env.sh

Następnie zaimportuj za pomocą skryptu cron:

env - `cat /path/to/my_env.sh` /bin/sh

Podejście 4:

W niektórych przypadkach możesz ustawić globalne zmienne cron w /etc/default/cron. Istnieje jednak pewien element ryzyka, ponieważ zostaną one ustawione dla wszystkich zadań cron.

cyberx86
źródło
Podejście 2 jest najlepsze dla serwerów, na których masz wrażliwe rzeczy, które nie powinny trafić dysku w zmienne env - hasła, klucze API itp. Działa dla mnie cuda, więc dziękuję.
ap
Podejście 4 działało dla mnie w środowisku dokera, w którym silnik dokera ustawia zmienne środowiskowe. Aby to zadziałało, musiałem zapisać swoją env w punkcie wejścia dokera. Kompletne rozwiązanie jest tutaj: github.com/rayyanqcri/swarm-scheduler
hammady
Czy mógłbyś opracować dla mnie podejście 3? Kiedy próbuję go zaimportować, otrzymujębash: SHELL=/bin/bash: No such file
KuboMD
1

Cron tworzy swoją WŁASNĄ powłokę przy użyciu określonego sposobu działania.

Tak więc, jeśli chcesz zachować tę samą zmienną użytkownika, spróbuj uruchomić ją z własnym użytkownikiem, zamiast rootem lub innym użytkownikiem.

Lub

Najlepszym sposobem jest eksport tych zmiennych we własnym skrypcie.

Farhan
źródło
1

W RedHat CentOS możesz ustawić /etc/rc.d/init.d/functions domyślną ŚCIEŻKĘ na stałe. /etc/rc.d/crond wywołuje funkcje podczas uruchamiania.

użytkownik215450
źródło
0

Miałem podobny problem z AWS. Tak to rozgryzłem

which python3

podał mi /usr/bin/local/python3lokalizację

i wtedy

. $HOME/.profile; /usr/local/bin/python3 /home/ubuntu/your_script.py
Al Po
źródło