commande non exécutée dans cron (systemctl suspend)

12

J'ai cet ensemble de cronjob:

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

Et ça ne marche pas. Mais je peux l'exécuter dans un shell et cela fonctionne. Je ne comprends pas ce qui pourrait ne pas fonctionner.

EDIT Rediriger la sortie d'erreur vers /tmp/errordonne ceci:

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

Ma question est alors: les cronjobs sont-ils exécutés en tant qu'utilisateur spécial ( cronpar exemple), ce qui expliquerait que mon utilisateur peut exécuter la commande, mais pas cronlui-même?

Explication supplémentaire:

  • Ceci est un exemple minimal pour montrer un problème que j'ai dans un script (qui a plus de sens que la seule commande fournie ici)

  • systemctlfait partie de systemd. Je pense que le redémarrage, l'arrêt, la suspension fonctionnent avec un utilisateur non root avec systemd. Quoi qu'il en soit, cela fonctionne sur mon système.

  • Enfin, j'utilise Arch Linux et /bin, /usr/sbin, /sbinsont tous les liens symboliques à /usr/bin.

Pente
la source
1
Qu'essayez-vous exactement de faire ici? Que fait la commande lorsque vous l'exécutez dans le shell?
terdon
Il suspend mon ordinateur
Gradient
Et voulez-vous que cela se produise à chaque minute? Votre systemctlest /usr/bindedans et il accepte suspendcomme ça? Quel * nix utilisez-vous?
terdon
1
Non, c'est un exemple. Il s'agit en fait d'un script qui s'arrête lorsque la batterie est faible. Mais c'est la partie de mon script qui ne fonctionne pas. J'ai essayé de donner un exemple minimal du problème (même si cela n'a aucun sens).
Gradient
2
OK, car cette question recueille des votes serrés, veuillez la modifier pour ajouter ces informations supplémentaires. Votre distribution est importante ( systemctl suspendne fonctionne pas sur les distributions Debian ou RedHat) et explique donc que vous ne voulez pas vraiment faire ce que vous montrez :). Essayez également d'ajouter 2> /tmp/errorou quelque chose pour capturer les erreurs que vous pourriez rencontrer. Enfin, dites-nous quel utilisateur exécute cette crontab.
terdon

Réponses:

6

Je ne peux pas vraiment répondre comme tel mais je pense que je peux vous orienter dans la bonne direction. J'ai trouvé cela sur la page Arch Wiki de systemd:

polkit est nécessaire pour la gestion de l'alimentation. Si vous êtes dans une session utilisateur systemd-logind locale et qu'aucune autre session n'est active, les commandes suivantes fonctionneront sans privilèges root. Sinon (par exemple, parce qu'un autre utilisateur est connecté à un tty), systemd vous demandera automatiquement le mot de passe root.

[liste des différentes commandes systemctl]

suspension de systemctl

Cela me suggère les possibilités suivantes:

  1. Vous avez un autre utilisateur connecté. Peut-être vous êtes-vous connecté via un tty?

  2. cronexécute ses commandes à l'aide de /bin/sh. Par défaut , sur Arch, il s'agit d'un lien symbolique vers /bin/bash. Cela signifierait que crondémarre un shell bash non interactif qui détecte alors qu'une autre session utilisateur est en cours d'exécution (la vôtre), il n'a donc pas le droit de s'exécuter systemctlmalgré son exécution en tant qu'utilisateur.

Donc, si votre problème est dû au fait qu'il cronn'est pas autorisé à s'exécuter systemctlparce que vous êtes déjà connecté, vous pourrez peut-être contourner cela en jouant avec polkit mais je n'y ai aucune expérience, je ne peux donc pas vous aider.

terdon
la source
Je vous remercie! La première option peut être éliminée car je suis capable d'exécuter la commande dans un shell. Mais je ferai plus de recherches sur la deuxième option.
Gradient
@Gradient avez-vous découvert comment résoudre ce problème? Je me bats avec le même problème.
AkiRoss
Pourriez-vous expliquer plus en détail la deuxième possibilité? Existe-t-il un moyen de confirmer que c'est bien le problème? J'ai exécuté wet à uptimepartir des scripts exécutés par cron. Leurs sorties ont indiqué qu'il n'y avait qu'un seul utilisateur. Alors, cela signifie-t-il qu'il y a un autre problème?
Anmol Singh Jaggi
3

Une solution de contournement simple consiste à utiliser le crontab de root au lieu du vôtre. Modifiez-le avec:

$ sudo crontab -e

au lieu de:

$ crontab -e
Frederik Baetens
la source
Il exécute les commandes en tant que root plutôt que votre utilisateur.
Frederik Baetens
Cela ne devrait pas être une pratique recommandée ... faites fonctionner la commande pour l'utilisateur.
plitter
1

Citant d' ici :

L'autre réponse est super! Mais cela nécessite un cron racine.

Si vous voulez mettre en veille prolongée depuis un cron non sudo, il y a 2 options:

1. Utilisation de polkit

Créez un fichier contenant les éléments suivants:

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

nommé com.0.enable-hibernation-from-cron.pkladans le répertoire /etc/polkit-1/localauthority/50-local.d/.

Une explication est donnée ici .

2. Utiliser visudo

Citant d' ici :

Si les utilisateurs doivent uniquement être autorisés à utiliser les commandes d'arrêt, mais ne disposent pas d'autres privilèges sudo, ajoutez en tant que root les éléments suivants à la fin de l' /etc/sudoersutilisation de la visudocommande.

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

Remplacez uservotre nom d'utilisateur et hostnamele nom d'hôte de la machine.
Désormais, votre utilisateur peut arrêter sudo systemctl poweroffet redémarrer avec sudo systemctl reboot. Les utilisateurs souhaitant éteindre un système peuvent également utiliser sudo systemctl halt.
Utilisez la balise NOPASSWD: uniquement si vous ne souhaitez pas être invité à saisir votre mot de passe.

Dans mon cas, la ligne exacte est:

anmol ALL=NOPASSWD: /bin/systemctl hibernate

(Notez que l'emplacement de systemctlpeut être différent sur votre système.)

Après cela, vous pouvez écrire sudo systemctl hibernatefron cron pour hiberner.

Remarque: la modification directe /etc/sudoersest mauvaise ; créez plutôt un fichier sudoers personnalisé en /etc/sudoers.d/utilisant la commande - sudo visudo -f /etc/sudoers.d/custom.

Anmol Singh Jaggi
la source
0

Si vous utilisez le système crontab, vous oubliez le champ utilisateur. Essayer:

* * * * * root /usr/bin/systemctl suspend
Martin von Wittich
la source
Êtes-vous sûr qu'il existe un champ utilisateur? Je n'ai jamais vu de cronjob avec ça auparavant. Quoi qu'il en soit, la commande fonctionne lorsque je l'exécute en tant qu'utilisateur dans un shell.
Gradient
2
@Gradient il y a un champ utilisateur si vous utilisez /etc/crontab, est-ce un tableau croisé que vous avez créé avec cron -evotre utilisateur normal?
terdon
C'est un crontab que j'ai créé avec crontab -eun utilisateur normal.
Gradient
votre compte d'utilisateur normal n'est probablement pas autorisé à fonctionner systemctl suspendsans sudo.
cas
0

Vous devez utiliser le fichier de configuration systemd dans /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
la source