OVH Cloud OVH Cloud

r

30 réponses
Avatar
Christophe PEREZ
Bonjour,

Bon, j'ai déjà eu du mal à trouver un titre. Ça doit bien démontrer que
ce n'est pas clair dans ma tête. Pourtant l'exemple est assez simple est
parlant.

Depuis peu (sans doute après des mises à jour), j'ai un comportement qui
a légèrement changé.
J'ai un script1 (en bash) sur ma machine (gentoo), qui lance une
commande :
---------------------------- %< ------------------------------
ssh -x $DISTUSER@$HOST script_distant
---------------------------- %< ------------------------------

le script distant, fait (entre autres) :
---------------------------- %< ------------------------------
1: CMD="DISPLAY=:0 xcowsay --cow-size=large --at=200,200 -t 60"
2: MSG="un message"
3: echo "un echo"
4: eval $CMD "$MSG" < /dev/null >/dev/null 2>&1 &
---------------------------- %< ------------------------------

Jusqu'à ces derniers jours, l'ensemble me rendait la main juste après
l'affichage du echo, sans plus attendre.
Depuis, l'ensemble ne me rend la main qu'après le timeout de la commande
xcowsay (ligne 4), soit 60 secondes après.
Pourtant, la ligne 4: rend bien la main aussitôt, je l'ai vérifié. Si je
lance directement script_distant sur la machine distante, le script me
rend la main aussitôt. C'est quand je le lance par ssh que le
comportement change. Le script ne se termine pas tant que xcowsay est
affiché. Et ça, c'est nouveau.
Je ne souhaite pas mettre & à l'appel :
---------------------------- %< ------------------------------
ssh -x $DISTUSER@$HOST script_distant &
---------------------------- %< ------------------------------
parce que du coup, ça me rend la main immédiatement, avant même
l'affichage du echo (ici, je simplifie l'exemple, ça va plus loin qu'un
simple echo).

J'espère avoir été clair, mais j'en doute quand même un peu :)

Si vous avez un idée, une explication, ou mieux une solution, je vous en
remercie d'avance.

10 réponses

1 2 3
Avatar
Christophe PEREZ
Le Thu, 05 Jan 2017 23:35:53 +0000, Christophe PEREZ a écrit :
De toutes les façons, je me rends compte qu'un script contenant juste :
sleep 5 &
ne me rend pas la main si exécuté à distance par ssh, alors qu'il rend
bien la main si exécuté en local.

Ça mérite confirmation, mais il semble que :
------------------------------- %< ----------------------------
{ sleep 60 && xset +dpms ; } </dev/null >/dev/null 2>&1 &
------------------------------- %< ----------------------------
fasse l'affaire.
Avatar
Nicolas George
Christophe PEREZ , dans le message <o4ml8p$nq6$, a
écrit :
Alors là, même si je vois un peu l'idée, je ne sais pas trop ce que je
dois faire.

Ce que tu as fait.
------------------------------- %< ----------------------------
setsid sleep 5 < /dev/null > /dev/null 2 > /dev/null
------------------------------- %< ----------------------------

Ton script s'écrit plus correctement :
setsid sleep 5 2 < /dev/null > /dev/null
Car « 2 > » n'est pas la même chose que « 2> », le 2 est un argument,
donc il va mieux avant les redirections, et pour le même FD, la dernière
redirection compte.
Avec le script corrigé :
ssecem ~ $ date; ssecem "setsid sleep 50 < /dev/null > /dev/null 2> /dev/null"; date
Fri Jan 6 10:40:50 CET 2017
Fri Jan 6 10:40:50 CET 2017
ssecem ~ $ pgrep sleep
25637
En revanche, si tu ajoutes un & à la fin, tu tues l'effet de setsid, en
quelque sorte. C'est compliqué.
Avatar
Christophe PEREZ
Le Fri, 06 Jan 2017 09:44:17 +0000, Nicolas George a écrit :
Ton script s'écrit plus correctement :
setsid sleep 5 2 < /dev/null > /dev/null
Car « 2 > » n'est pas la même chose que « 2> », le 2 est un argument,
donc il va mieux avant les redirections, et pour le même FD, la dernière
redirection compte.

D'accord, mais, ça ne me rend toujours pas la main quand je le lance par
ssh.
Avec le script corrigé :
ssecem ~ $ date; ssecem "setsid sleep 50 < /dev/null > /dev/null 2>
/dev/null"; date

Je ne comprends plus rien. Ça, c'est la forme que J'ai utilisée. Pas
celle que tu me proposes.
De plus, si j'utilise ce que tu proposes, même en local ça ne me rend pas
la main.
En revanche, si tu ajoutes un & à la fin, tu tues l'effet de setsid, en
quelque sorte. C'est compliqué.

Je comprends bien, mais comment utiliser setsid avec un groupe de
commandes "encadrées" par { } ?
Avatar
Nicolas George
Christophe PEREZ , dans le message <o4o9j4$les$, a
écrit :
ssecem ~ $ date; ssecem "setsid sleep 50 < /dev/null > /dev/null 2>
/dev/null"; date

Je ne comprends plus rien. Ça, c'est la forme que J'ai utilisée. Pas
celle que tu me proposes.

Tu m'as mal lu, je ne t'ai pas proposé quoi que ce soit, je t'ai montré
ce que tu écrivais sans le savoir. Regarde bien les différences avec ma
ligne de commande.
De plus, si j'utilise ce que tu proposes, même en local ça ne me rend pas
la main.

Au point où on en est, je pense qu'il faudrait que tu passes un peu
moins de temps à mettre des pointillés pour découper tes commandes et
que tu les colles un peu plus exactement comme tu les as testées.
Je comprends bien, mais comment utiliser setsid avec un groupe de
commandes "encadrées" par { } ?

Ce n'est pas possible. setsid, comme toute commande de ce genre bien
élevée (nice, env, etc.), fait ce qu'elle a à faire puis exécute ses
arguments. Si tu n'es pas à l'aise avec ça, je pense qu'il faudrait que
tu te documentes sur les principes de base de gestion des processus
Unix : fork(), exec() et le rôle du shell dans tout ça.
Si tu veux exécuter plusieurs commandes après le setsid, il faut quelque
chose qui le fasse, par exemple un shell avec l'option -c.
Avatar
Christophe PEREZ
Le Fri, 06 Jan 2017 18:14:18 +0000, Nicolas George a écrit :
Au point où on en est, je pense qu'il faudrait que tu passes un peu
moins de temps à mettre des pointillés pour découper tes commandes et
que tu les colles un peu plus exactement comme tu les as testées.

A part les pointillés pour aider à la lecture (à mon sens), je les ai
tapées telles que testées.
Je comprends bien, mais comment utiliser setsid avec un groupe de
commandes "encadrées" par { } ?

Ce n'est pas possible.

Donc setsid ne répond pas à la problématique ;)
Si tu veux exécuter plusieurs commandes après le setsid, il faut quelque
chose qui le fasse, par exemple un shell avec l'option -c.

On va laisser tomber tout ça qui devient bien trop complexe au vu du
besoin.
J'ai donc changé mon fusil d'épaule, en ne tentant plus de différer
l'action d'un délai arbitraire, mais en scrutant le moment où mes
commandes deviennent utiles. Le mode de scrutation utilisé n'est
certainement pas idéal, mais au moins, je n'aurai pas à apprendre 150000
choses qui ne me serviront plus ou que j'aurai oubliées quand j'en aurai
à nouveau besoin dans 20 ans (si je suis encore vivant) :)
Merci encore pour ton aide.
Avatar
Christophe PEREZ
Le Fri, 06 Jan 2017 09:44:17 +0000, Nicolas George a écrit :
ssecem ~ $ date; ssecem "setsid sleep 50 < /dev/null > /dev/null 2>
/dev/null"; date Fri Jan 6 10:40:50 CET 2017 Fri Jan 6 10:40:50 CET
2017

Et comme je suis particulièrement têtu moi aussi :D :
$ date ; setsid sleep 5 </dev/null >/dev/null 2>/dev/null ; date
ven. janv. 6 16:31:58 AST 2017
ven. janv. 6 16:31:58 AST 2017
$ date ; ./distant.sh ; date
ven. janv. 6 16:32:16 AST 2017
ven. janv. 6 16:32:21 AST 2017
$ cat ./distant.sh
setsid sleep 5 </dev/null >/dev/null 2>/dev/null
Donc le résultat n'est pas le même dans le shell et dans un script...
Avatar
Nicolas George
Christophe PEREZ , dans le message <o4ov36$r6v$, a
écrit :
$ date ; setsid sleep 5 </dev/null >/dev/null 2>/dev/null ; date
ven. janv. 6 16:31:58 AST 2017
ven. janv. 6 16:31:58 AST 2017
$ date ; ./distant.sh ; date
ven. janv. 6 16:32:16 AST 2017
ven. janv. 6 16:32:21 AST 2017
$ cat ./distant.sh
setsid sleep 5 </dev/null >/dev/null 2>/dev/null

Note : ton script ne commence pas par #! et le chemin d'un interpréteur,
donc tu ne peux pas prédire comment il sera exécuté, ni même s'il pourra
l'être en général.
Donc le résultat n'est pas le même dans le shell et dans un script...

Oui, il y a une subtilité : setsid met en arrière plan si et seulement
si le contrôle de jobs est activé :
$ date; zsh -c "setopt monitor; date; setsid sleep 5; date"; date
Sat Jan 7 11:18:29 CET 2017
Sat Jan 7 11:18:29 CET 2017
Sat Jan 7 11:18:29 CET 2017
Sat Jan 7 11:18:29 CET 2017
$ date; zsh -c "date; setsid sleep 5; date"; date
Sat Jan 7 11:18:50 CET 2017
Sat Jan 7 11:18:50 CET 2017
Sat Jan 7 11:18:55 CET 2017
Sat Jan 7 11:18:55 CET 2017
(les redirections ne seront utiles que pour SSH)
Dans un script, le contrôle de jobs est désactivé, donc il faut
effectivement le &, sur le setsid lui-même ; hors d'un script, mettre le
& à un mauvais endroit va cacher l'effet de setsid.
Avatar
Nicolas George
Christophe PEREZ , dans le message <o4ouh9$q4e$, a
écrit :
Donc setsid ne répond pas à la problématique ;)

C'est setsid, pas dwim. Mais c'est bien une brique indispensable pour
séparer un processus de son père.
On va laisser tomber tout ça qui devient bien trop complexe au vu du
besoin.

Je pense que tu surestimes largement la complexité de ce que j'évoque et
que tu sous-estimes tout aussi largement le bénéfice qu'il y a à bien
comprendre ce que l'on fait.
Avatar
Christophe PEREZ
Le Sat, 07 Jan 2017 10:23:02 +0000, Nicolas George a écrit :
C'est setsid, pas dwim.

Hein ?
Mais c'est bien une brique indispensable pour séparer un processus de
son père.

Je n'en doute pas.
Je pense que tu surestimes largement la complexité de ce que j'évoque

Hmmm... je sais ce que je ressens ;)
et que tu sous-estimes tout aussi largement le bénéfice qu'il y a à bien
comprendre ce que l'on fait.

Ah non, pas du tout. Je le mets juste en rapport avec le besoin que j'en
ai.
Je ne peux (ni ne cherche d'ailleurs) à tout comprendre ni maîtriser.
Je fais mes petits scripts dans mon coin juste pour me rendre service. Je
suis à 99% seul utilisateur direct de ces scripts.
Ils ont même souvent une durée de vie limitée.
Je ne souhaite donc pas y passer trop de temps. J'essaye de faire les
choses biens, mais de garder un bon compromis entre l'efficacité et le
temps passé.
Mais je suis parfaitement conscient que beaucoup de choses qui
m'échappent, plus ou moins volontairement, peuvent être très utiles et
importantes pour d'autres, dans d'autres contextes.
Avatar
Christophe PEREZ
Le Sat, 07 Jan 2017 10:21:35 +0000, Nicolas George a écrit :
Note : ton script ne commence pas par #! et le chemin d'un interpréteur,
donc tu ne peux pas prédire comment il sera exécuté, ni même s'il pourra
l'être en général.

Oui, oui, bien sûr, dans le cas général. Mais ici dans ce cas particulier
sur ma machine unique avec bash juste aux fins de tests pour ce ng, cela
me semblait acceptable.
Sinon, tous mes scripts contiennent toujours #!/bin/bash
Oui, il y a une subtilité : setsid met en arrière plan si et seulement
si le contrôle de jobs est activé :
$ date; zsh -c "setopt monitor; date; setsid sleep 5; date"; date Sat
Jan 7 11:18:29 CET 2017 Sat Jan 7 11:18:29 CET 2017 Sat Jan 7
11:18:29 CET 2017 Sat Jan 7 11:18:29 CET 2017
$ date; zsh -c "date; setsid sleep 5; date"; date Sat Jan 7 11:18:50
CET 2017 Sat Jan 7 11:18:50 CET 2017 Sat Jan 7 11:18:55 CET 2017 Sat
Jan 7 11:18:55 CET 2017

Ok.
(les redirections ne seront utiles que pour SSH)

J'avais bien compris ça aussi, mais je partais du principe que pour que
ça fonctionne par ssh, il faut au moins que ça fonctionne en local, donc
j'ai juste conservé le même script pour les tests.
Dans un script, le contrôle de jobs est désactivé, donc il faut
effectivement le &, sur le setsid lui-même ; hors d'un script, mettre le
& à un mauvais endroit va cacher l'effet de setsid.

Là c'est clair. Reste plus qu'à comprendre cette histoire de contrôle de
jobs ;)
Merci pour les infos.
1 2 3