Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Créer un screen depuis Cron

7 réponses
Avatar
Cyprien Nicolas
Bonjour,

Sur une machine Debian Wheezy, j'ai un script qui lance un Bot IRC
(écrit en Haskell) s'il ne tourne pas déjà. Le script se contente de
faire un pgrep, et un exec si nécessaire.

Il arrive que le Bot meurt, soit parce que je le tue, soit parce que le
serveur est rebooté, et j'aimerais donc le relancer automatiquement. Je
n'ai pas besoin qu'il soit absolument toujours en ligne, un cron qui
cherche à le relancer toutes les heures me va bien.

J'ai besoin que le bot tourne dans un screen, afin de pouvoir regarder
les logs brut IRC si nécessaire.

Je lance le bot depuis le dedans d'un screen, avec le script qui va
bien, ou alors, directement en une ligne :

screen -dmS fedebot bash -c /home/fulax/bot-start.sh

Pour la tâche planifiée, j'ai inscrit la ligne suivante dans ma crontab:

0 * * * * /usr/bin/screen -dmS fedebot bash -c /home/fulax/bot-start.sh

Cependant, lorsque je lance le screen à la main avec la première
commande, ça fonctionne, le bot démarre si nécessaire, et tourne. En
revanche, dans le cas cron, le bot est bien lancé, mais meurt sans
explication dans les secondes qui suivent.

Si le bot ne se lançait pas du tout dans le second cas, je pourrais
suspecter un problème d'environnement, ou quelque chose du genre. Mais
il se lance et meurt juste après, comme s'il avait reçu un SIGINT.

J'avoue que je suis à court d'idées, donc si vous en avez, je suis
curieux. :-)

--
« Ceci n'est pas une signature. » — René Magritte (Apocryphe)

7 réponses

Avatar
Nicolas George
Cyprien Nicolas , dans le message <kp1n88$80s$, a écrit :
J'ai besoin que le bot tourne dans un screen, afin de pouvoir regarder
les logs brut IRC si nécessaire.



Ça me semble une mauvaise conception : les terminaux sont destinés aux
applications principalement interactives, et en utiliser un pour ça, avec en
plus toute la surcharge de screen, est inadapté à cet usage.

Une solution infiniment plus simple, et aussi plus pratique en fait, est
d'envoyer les logs de ton bot dans des fichiers.
Avatar
yamo'
Salut,

Cyprien Nicolas a tapoté, le 09/06/2013 13:00:
J'avoue que je suis à court d'idées, donc si vous en avez, je suis
curieux. :-)



Tu as essayé avec nohup?

--
Stéphane <http://pasdenom.info/fortune/?>
BOFH excuse #260:

We're upgrading /dev/null
Avatar
Nicolas George
yamo' , dans le message <kp23pu$rt1$, a écrit :
Tu as essayé avec nohup?



Rappel : nohup est une commande complètement idiote, il ne faut jamais
l'utiliser, tout ce qu'elle fait peut être fait en mieux par d'autres
moyens.
Avatar
Cyprien Nicolas
On 06/09/2013 01:25 PM, Nicolas George wrote:
Ça me semble une mauvaise conception : les terminaux sont destinés aux
applications principalement interactives, et en utiliser un pour ça, avec en
plus toute la surcharge de screen, est inadapté à cet usage.



Certes, je comprends ton point de vue, mais dans tous les cas, ça
n'explique pas le comportement observé.

Une solution infiniment plus simple, et aussi plus pratique en fait, est
d'envoyer les logs de ton bot dans des fichiers.



Oui, j'ai fait ça via exec dans mon script, juste avant le exec ./bot

--
« Ceci n'est pas une signature. » — René Magritte (Apocryphe)
Avatar
Cyprien Nicolas
On 06/09/2013 04:34 PM, yamo' écrivît :
Tu as essayé avec nohup?



Oui, et même comportement.

Mais j'ai pu trouver l'erreur, la locale qui était pas bonne. Le code
Haskell levait une exception de décodage utf-8, et le gestionnaire
d'exception par défaut tuait le processus. Une fois mis la bonne locale
dans le script qui démarre le bot, ça fonctionne. C'était donc bien une
erreur d'environnement

--
« Ceci n'est pas une signature. » — René Magritte (Apocryphe)
Avatar
Cyprien Nicolas
On 06/09/2013 05:52 PM, Nicolas George écrivît :
Rappel : nohup est une commande complètement idiote, il ne faut
jamais l'utiliser, tout ce qu'elle fait peut être fait en mieux par
d'autres moyens.



« complètement idiote », c'est à dire qu'elle ne fait pas ce qu'il faut,
ou quelle a un comportement bizarre dans certaines situations ?

Je veux bien mettre un

exec <&- >mon-fichier.log 2>&1
exec ./mon-programme

à la place de

exec >mon-fichier.log
exec nohup ./mon-programme

mais je suis pas certain de peser les pour et les contre.

--
« Ceci n'est pas une signature. » — René Magritte (Apocryphe)
Avatar
Nicolas George
Cyprien Nicolas , dans le message <kp29kb$o96$, a écrit :
« complètement idiote », c'est à dire qu'elle ne fait pas ce qu'il faut,
ou quelle a un comportement bizarre dans certaines situations ?



Qu'elle ne fait pas ce qu'il faut. Elle fait ignorer les SIGHUP alors que la
manière correcte de procéder est de détacher le processus de son terminal de
contrôle.

exec <&- >mon-fichier.log 2>&1



Le <&- est une très mauvaise idée : ça ferme l'entrée standard, et beaucoup
de programmes vont mal se comporter si leur fd 0 est fermé. Il faut faire
« < /dev/null ». C'est aussi ce que fait nohup, sur ce point il n'y a pas de
problème.

exec ./mon-programme

à la place de

exec >mon-fichier.log
exec nohup ./mon-programme

mais je suis pas certain de peser les pour et les contre.



Du point de vue des redirections, modulo la correction ci-dessus, c'est
rigoureusement équivalent. Le faire dans le shell est légèrement plus
efficace puisqu'il n'y a pas un programme supplémentaire à charger en
mémoire, mais c'est négligeable.

C'est au niveau de la gestion du terminal de contrôle que nohup fait
n'importe quoi :

rt_sigaction(SIGHUP, {SIG_IGN, [HUP], SA_RESTORER|SA_RESTART, 0x2b0c4e6bc310}, {SIG_DFL, [], 0}, 8) = 0

La bonne commande à utiliser est setsid :

exec setsid programme < /dev/null >& out.log

(>& est un idiome de zsh pour > ... 2>&1)