polecenie nie działa w cronie (zawieszenie systemctl)

12

Mam ten zestaw cronjob:

* * * * * /usr/bin/systemctl suspend

I to nie działa. Ale mogę uruchomić go w powłoce i działa. Nie rozumiem, co może nie działać.

EDYCJA Wyjście błędu przekierowania /tmp/errordaje:

Failed to issue method call: Access denied
Failed to issue method call: Access denied

Moje pytanie brzmi zatem: czy cronjobs są uruchamiane jako specjalny użytkownik ( cronna przykład), co wyjaśniałoby, że mój użytkownik może uruchomić polecenie, ale nie cronsam?

Dodatkowe wyjaśnienie:

  • To minimalny przykład pokazujący problem, który mam w skrypcie (ma to większy sens niż podane tutaj pojedyncze polecenie)

  • systemctljest częścią systemd. Myślę, że restart, zamknięcie, zawieszenie działają z użytkownikiem innym niż root systemd. W każdym razie działa w moim systemie.

  • Wreszcie, używam Arch Linux i /bin, /usr/sbin, /sbinsą wszystkie dowiązania do /usr/bin.

Gradient
źródło
1
Co dokładnie próbujesz tutaj zrobić? Co robi polecenie po uruchomieniu go w powłoce?
terdon
Zawiesza mój komputer
Gradient
Czy chcesz, żeby tak się działo co minutę? Twój systemctljest w /usr/binśrodku i tak to akceptuje suspend? Jakiego * nix używasz?
terdon
1
Nie, to jest przykład. Jest tak naprawdę w skrypcie, który zawiesza się, gdy poziom naładowania baterii jest niski. Ale ta część mojego skryptu nie działa. Próbowałem podać minimalny przykład problemu (nawet jeśli wydaje się to nie mieć sensu).
Gradient
2
OK, ponieważ to pytanie zbiera głosy zbliżone, edytuj je, aby dodać te dodatkowe informacje. Twoja dystrybucja jest ważna ( systemctl suspendnie działa na dystrybucjach Debiana lub RedHata), więc wyjaśnia, że ​​tak naprawdę nie chcesz robić tego, co pokazujesz :). Spróbuj także dodać 2> /tmp/errorcoś lub coś, aby uchwycić ewentualne błędy. Na koniec powiedz nam, który użytkownik uruchamia ten crontab.
terdon

Odpowiedzi:

6

Naprawdę nie mogę odpowiedzieć jako taki, ale myślę, że mogę skierować cię w dobrym kierunku. Znalazłem to w Arch Wiki stronie o systemd:

pakiet polkit jest niezbędny do zarządzania energią. Jeśli jesteś w lokalnej sesji użytkownika logd systemd i żadna inna sesja nie jest aktywna, następujące polecenia będą działać bez uprawnień roota. Jeśli nie (na przykład ponieważ inny użytkownik jest zalogowany do tty), systemd automatycznie poprosi o hasło roota.

[lista różnych poleceń systemctl]

systemctl zawiesza

To sugeruje mi następujące możliwości:

  1. Masz zalogowanego innego użytkownika. Być może zalogowałeś się przez tty?

  2. cronuruchamia polecenia za pomocą /bin/sh. Domyślnie w Arch jest to dowiązanie symboliczne do /bin/bash. Oznaczałoby cronto uruchomienie nieinteraktywnej powłoki bash, która następnie wykrywa, że ​​jest uruchomiona inna sesja użytkownika (twoja), więc nie ma ona prawa do uruchomienia systemctlpomimo działania jako użytkownik.

Więc jeśli twój problem jest spowodowany tym, że cronnie systemctlmożesz uruchomić, ponieważ jesteś już zalogowany, możesz być w stanie obejść ten problem, grając z polkit, ale nie mam tam doświadczenia, więc nie mogę pomóc.

terdon
źródło
Dziękuję Ci! Pierwszą opcję można wyeliminować, ponieważ jestem w stanie wykonać polecenie w powłoce. Ale zrobię więcej badań na temat drugiej opcji.
Gradient
@Gradient odkryłeś, jak to naprawić? Walczę z tym samym problemem.
AkiRoss
Czy mógłbyś bardziej szczegółowo wyjaśnić drugą możliwość? Czy jest jakiś sposób, aby potwierdzić, że to rzeczywiście jest problem? Wykonałem wi uptimeze skryptów uruchamianych przez crona. Ich wyniki wskazywały, że był tylko użytkownik. Czy to oznacza, że ​​jest jakiś inny problem?
Anmol Singh Jaggi
3

Łatwym obejściem jest użycie crontab roota zamiast własnego. Edytuj za pomocą:

$ sudo crontab -e

zamiast:

$ crontab -e
Frederik Baetens
źródło
Uruchamia polecenia jako root, a nie użytkownik.
Frederik Baetens
Nie powinno to być zalecaną praktyką ... spraw, aby polecenie działało dla użytkownika.
plitter
1

Cytowanie stąd :

Druga odpowiedź jest świetna! Ale wymaga root crona.

Jeśli chcesz hibernować z crona innego niż sudo, istnieją 2 opcje:

1. Korzystanie z polkit

Utwórz plik zawierający następujące elementy:

[Enable hibernate to be run via cron]
Identity=unix-user:*
Action=org.freedesktop.login1.hibernate;org.freedesktop.login1.hibernate-multiple-sessions
ResultAny=yes 

nazwany com.0.enable-hibernation-from-cron.pklaw katalogu /etc/polkit-1/localauthority/50-local.d/.

Wyjaśnienie podano tutaj .

2. Korzystanie z visudo

Cytowanie stąd :

Jeśli użytkownicy powinni mieć możliwość korzystania tylko z poleceń zamykania, ale nie mają innych uprawnień sudo, to jako root dodaj poniższe polecenie na końcu /etc/sudoerskorzystania z visudopolecenia.

user hostname =NOPASSWD: /usr/bin/systemctl poweroff,/usr/bin/systemctl halt,/usr/bin/systemctl reboot

Zastąp userswoją nazwę użytkownika i hostnamenazwę hosta urządzenia.
Teraz użytkownik może zamknąć sudo systemctl poweroffi ponownie uruchomić sudo systemctl reboot. Użytkownicy, którzy chcą wyłączyć system, mogą również korzystać sudo systemctl halt.
Użyj znacznika NOPASSWD: tylko wtedy, gdy nie chcesz otrzymywać monitu o podanie hasła.

W moim przypadku dokładna linia to:

anmol ALL=NOPASSWD: /bin/systemctl hibernate

(Uwaga: lokalizacja systemctlmoże być inna w systemie).

Następnie możesz napisać sudo systemctl hibernatefron cron do hibernacji.

Uwaga: Bezpośrednie modyfikowanie /etc/sudoersjest złe ; zamiast tego utwórz niestandardowy plik sudoers za /etc/sudoers.d/pomocą polecenia - sudo visudo -f /etc/sudoers.d/custom.

Anmol Singh Jaggi
źródło
0

Jeśli używasz crontab systemowego, zapominasz pola użytkownika. Próbować:

* * * * * root /usr/bin/systemctl suspend
Martin von Wittich
źródło
Czy na pewno jest pole użytkownika? Nigdy wcześniej nie widziałem z nim cronjobu. W każdym razie polecenie działa, gdy uruchamiam je jako użytkownik w powłoce.
Gradient
2
@Gradient jest pole użytkownika, jeśli używasz /etc/crontab, czy to jest crontab, który utworzyłeś cron -ejako zwykły użytkownik?
terdon
Jest to crontab, który utworzyłem crontab -ejako zwykły użytkownik.
Gradient
Twoje normalne konto użytkownika prawdopodobnie nie ma uprawnień do uruchamiania systemctl suspendbez sudo.
cas
-1

Musisz użyć pliku konfiguracji systemd w /etc/systemd/system

[Unit]
Description=Pimcore Events Processor

[Service]
WorkingDirectory=/var/www/html
ExecStart=/usr/bin/php run something
Restart=always
WatchdogSec=300 #in seconds
User=www-data
Group=www-data

[Install]
WantedBy=multi-user.target
James M.
źródło