Pytanie:
Domyślna powłoka dla problemu z cronem
cupakob
2012-10-10 13:02:53 UTC
view on stackexchange narkive permalink

Mam kilka poleceń, działają pod bash, ale nie jako cronjob. Aby zobaczyć, jaka jest przyczyna problemu, zapisuję dane wyjściowe w pliku, tutaj mój przykład:

  51 * * * * source ~ / .rvm / scripts / rvm >> stack.log 2>&1  

Zawartość pliku dziennika to:

  / bin / sh: 1: source: not found  

Oznacza to, że cron używa sh zamiast bash . Próbowałem to zmienić w /etc/crontab:

SHELL=/bin/bash

Ale to nie działa. Sprawdziłem w / etc / passwd i tutaj widzę, że demon używa sh jako domyślnej powłoki. Zarówno root , jak i pi mają domyślną powłokę bash .

  root: x: 0: 0: root : / root: / bin / bashdaemon: x: 1: 1: daemon: / usr / sbin: / bin / shpi: x: 1000: 1000: ,,,: / home / pi: / bin / bash  

Co powinienem zrobić, aby zmienić domyślną powłokę dla crona? Nie ustawiłbym / bin / bash dla użytkownika demona w / etc / passwd ... imho to nie jest dobry pomysł.

edit”:

  ls -l / bin / shlrwxrwxrwx 1 root root 4 30 marca 2012 r. / bin / sh -> myślnik  

tutaj zawartość /etc/crontab:

  # / etc / crontab: system-wide crontab # W przeciwieństwie do innych tabel crontab, których nie musisz uruchamiać polecenie `crontab '# do zainstalowania nowej wersji podczas edycji tego pliku # i plików w /etc/cron.d. Pliki te mają również pola nazw użytkowników, # których nie ma żadna inna lista crontab.SHELL = / bin / bashPATH = / usr / local / sbin: / usr / local / bin: / sbin: / bin: / usr / sbin: / usr / bin # mh dom mon dow polecenie użytkownika17 * * * * root cd / && run-parts --report /etc/cron.hourly25 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) #  
Dlaczego chcesz pobierać źródła w środowisku crons? Po prostu uruchomienie `~ / .rvm / scripts / rvm` nie działa? I _możesz_ mieć problemy z używaniem ~ w środowiskach innych niż bash.
Cztery odpowiedzi:
#1
+4
Krzysztof Adamski
2012-10-10 13:07:33 UTC
view on stackexchange narkive permalink

Większość takich przypadków (gdzie skrypt działa w powłoce, ale nie w cronie) jest spowodowana zmiennymi środowiskowymi, które różnią się w skrypcie. W wielu przypadkach problemem jest zmienna PATH . Możesz użyć pełnych ścieżek do wszystkich plików wykonywalnych, które uruchamiasz w skrypcie lub zmodyfikować PATH w pierwszym wierszu skryptu.

Aby śledzić takie problemy, możesz zacząć od zrzucenia dostępnych zmiennych środowiskowych do skryptu za pomocą polecenia env , na przykład: / usr / bin / env> /tmp/env.txt

nie mam żadnych zmiennych środowiskowych w moim skrypcie ... i / bin / env nie istnieje.
Nie, _zawsze_ masz jakieś zmienne środowiskowe w każdej powłoce. Jednym z przykładów jest wspomniana już ścieżka „PATH”. Spróbuj zamiast tego `/ usr / bin / env`. Lub użyj polecenia „which env”, aby sprawdzić, jaka jest Twoja pełna ścieżka do wykorzystania „env”.
#2
+4
Alex Chamberlain
2012-10-10 13:12:14 UTC
view on stackexchange narkive permalink

Używana powłoka to myślnik ; powłoka zgodna z POSIX, która została zaprojektowana tak, aby była znacznie mniejsza i bardziej stabilna niż bash.

Można by argumentować, że powinieneś pisać zadania cron być zgodne z POSIX. Ewentualnie spróbuj hermetyzować swoją logikę w skrypcie i wstaw przedrostek shebang

  #! / Usr / bin / env bash  
dlaczego #! / usr / bin / env bash a nie #! / bin / bash? jaka jest różnica?
IMHO nie dużo. Ściśle mówiąc, pozwala na przechowywanie „bash” w innym miejscu. Kto by to zrobił, nie wiem!
Próbowałem tego również ... Mam skrypt opakowujący bash, który wywołuje moje polecenie, ale to też nie działa. Ale błądzę, dlaczego zmiany w / etc / crontab nie powodują przełączenia na bash.
@cupakob Czy możesz wkleić cały plik `/ etc / crontab`?
możesz go znaleźć w moim poście
Myślę, że problem polega na tym, że „source” jest wbudowaną funkcją, która nie ma sensu działać samodzielnie.
pozwól nam [kontynuować tę dyskusję na czacie] (http://chat.stackexchange.com/rooms/6073/discussion-between-cupakob-and-alex-chamberlain)
#3
+3
Avio
2012-10-10 15:48:16 UTC
view on stackexchange narkive permalink

Czy jesteś pewien, że pozyskiwanie skryptu do cron jest absolutnie tym, co chcesz zrobić, a co ważniejsze, jest konieczne? Myślę, że to prawie zawsze zły pomysł.

Ponadto podczas edycji cron (a także innych narzędzi, które mogą być uruchamiane przez innych użytkowników i / lub inne powłoki), spróbuj wykonać krok po kroku podejście krokowe. Na przykład możesz przetestować swoje środowisko za pomocą czegoś takiego:

  42 * * * * bash -c "echo home --- $ HOME ---" >> / tmp / cron-temp .log 2>&142 * * * * bash -c "powłoka echo --- $ SHELL ---" >> /tmp/cron-temp.log 2>&1  

lub nawet:

  42 * * * * bash -c "export" >> /tmp/cron-temp.log 2>&1  

Dzięki temu możesz mieć dowód na swoje środowisko itp.

Odpowiadając na twoje pytanie, nie zmieniłbym powłoki dla cron . Po prostu powiedziałbym mu, aby zadzwonił do bash , a następnie pozwolił bash wywołać twoje skrypty.

$ SHELL nadal był 'sh', mimo że zmieniłem go w / etc / crontab
Tak, jest to również domyślne ustawienie w moim „cron”. Jak powiedziałem, nie zmieniłbym tego. Po prostu wywołaj swój skrypt przez `bash` z` bash -c "yourscript" `i wszystko powinno być w porządku (nie źródłuj swojego skryptu, prawdopodobnie go nie potrzebujesz!)
tak, to zadziała, ale chcę wiedzieć, dlaczego domyślna powłoka nie została zmieniona.
#4
+3
cupakob
2012-10-11 02:27:09 UTC
view on stackexchange narkive permalink

Więc .... mam dwa rozwiązania mojego problemu:

  1. Skrypt opakowujący polecenie bash, które w tej chwili wywołuję jako cronjob. Problem tutaj - do każdego cronjob potrzebuję jednego opakowania, a to nie jest dla mnie najlepsze rozwiązanie.

  2. Próbowałem nazwać skrypt ruby ​​jako cronjob. To nie działa, więc pomyślałem, że muszę wywołać „rvm use 1.9.3” i najpierw muszę wywołać „source ~ / .rvm / scripts / rvm”. I tu był mój błąd. W mojej instancji bash mam ścieżkę do ruby, ale nie jako cron. Po naprawieniu wszystko działa dobrze i mogę wykonywać moje skrypty ruby ​​jako cronjob.

Alex Chamberlain bardzo mi pomógł i dał mi najważniejszą wskazówkę (y) . Wielkie dzięki za pomoc !!!



To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...