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

[Q] test si le shell est interactif ou non

15 réponses
Avatar
Nicolas.MICHEL
Bonjour

Dans un script, je voudrais tester si ce script est lancé par le système
ou s'il est lancé en mode interactif, dons avec quelqu'un derrière ...
De façon à réagir automatiquement si c'est la crontab qui a lancé le
script et à pauser des questions si le script est lancé par quelqu'un.

Est-ce possible ?

Merci d'avance :)

--
Nicolas

10 réponses

1 2
Avatar
Luc.Habert.00__arjf
Nicolas MICHEL :

Dans un script, je voudrais tester si ce script est lancé par le système
ou s'il est lancé en mode interactif, dons avec quelqu'un derrière ...
De façon à réagir automatiquement si c'est la crontab qui a lancé le
script et à pauser des questions si le script est lancé par quelqu'un.


Je dirais d'avoir une option, ou une variable d'environnement qui controle
si il pause des questions. Mieux encore : séparer en deux scripts, l'un
posant les questions et appellant l'autre avec les réponses obtenues.

Si tu tiens à utiliser une heuristique foireuse, tu peux tester si tu es
lancé dans un terminal en regardant si « tty » réussit.

Avatar
Damien Wyart
* (Nicolas MICHEL) in fr.comp.os.unix:
Dans un script, je voudrais tester si ce script est lancé par le
système ou s'il est lancé en mode interactif, dons avec quelqu'un
derrière ...


Sur certains shells (bash, zsh, pour les autres je ne sais pas), la
variable $- contiendra un 'i' si on est en mode interactif.

--
DW

Avatar
Nicolas.MICHEL
Luc Habert wrote:

Je dirais d'avoir une option, ou une variable d'environnement qui controle
si il pause des questions. Mieux encore : séparer en deux scripts, l'un
posant les questions et appellant l'autre avec les réponses obtenues.

Si tu tiens à utiliser une heuristique foireuse, tu peux tester si tu es
lancé dans un terminal en regardant si « tty » réussit.


Merci Luc :)
Si j'ai bien tout compris, tu me proposes plusieures solutions.

La première serait de vérifier l'existance d'une variable
d'environnement qui n'existerait qu'en mode interactif ...

donc j'ai fait un script qui contient
#!/bin/bash
echo "$(set)" > qq1.txt"
echo "$(tty)" > ww1.txt

quand je le lance à la main, il me dit notament :
TERM=xterm-color
alors que si je fais exécuter par cron, il me dit :
TERM=dumb

est-ce à ce type de variable que tu pensais ?
Comme c'est un script qui va être déployé, modifier tous les .profile
n'est pas envisageable ...

Créer 2 scripts, l'un pour le mode interactif et l'autre pour cron
m'ennuyes pour des raisons de débuggage et ça risque de paraitre
complexe à mes collègues ...

Enfin tu me suggère de regarder tty ...
en effêt, en interactif il me donne un résultat variable du genre
/dev/ttyp5
alors que via cron, ça dit :
not a tty

J'ai souvent entendu parler de tty, mais j'ai jamais compris ce que
c'est au juste. <:o)

Est-ce que ces 2 solutions sont fiables ?
($TERM et tty) Ou faut-il me méfier ?
J'ai l'embaras du choix là.

Merci encore :)

--
Nicolas

Avatar
Nicolas.MICHEL
Damien Wyart wrote:

* (Nicolas MICHEL) in fr.comp.os.unix:
Dans un script, je voudrais tester si ce script est lancé par le
système ou s'il est lancé en mode interactif, dons avec quelqu'un
derrière ...


Sur certains shells (bash, zsh, pour les autres je ne sais pas), la
variable $- contiendra un 'i' si on est en mode interactif.


J'ai fait ça :
#!/bin/bash
echo "$-" > ee5.txt

et ça donne ça en interactif comme via cron :
$ cat ee5.txt
hB

par contre :

$ echo $SHELL
/bin/bash
$ echo $-
himBH

Donc amha, si tu lance un script à la main, il ne sera pas concidéré
comme interactif ... non ?
--
Nicolas


Avatar
Damien Wyart
* (Nicolas MICHEL) in fr.comp.os.unix:
Donc amha, si tu lance un script à la main, il ne sera pas concidéré
comme interactif ... non ?


En effet, j'ai mal interprété la question et cru qu'elle faisait
référence au caractère interactif du shell et pas du lancement d'un
script. Désolé.

--
DW

Avatar
Luc.Habert.00__arjf
Nicolas MICHEL :

La première serait de vérifier l'existance d'une variable
d'environnement qui n'existerait qu'en mode interactif ...


Non, au contraire. Tu te choisis un nom de variable qui ne conflicte avec
rien d'autre, et tu définis cette variable au moment d'appeller le script
(par exemple dans la crontab) lorsque tu ne veux pas de question.

Créer 2 scripts, l'un pour le mode interactif et l'autre pour cron
m'ennuyes pour des raisons de débuggage


Pourquoi? La programmation modulaire, ça facilite le débugage, au contraire.
Je ne te dis pas de dupliquer le code.

et ça risque de paraitre complexe à mes collègues ...


Là, c'est toi qui les connais mieux que moi, c'est sûr. Mais je ne vois pas
ce qu'on peut trouver de complexe à :

scriptA avec liste d'arguments complète bien spécifiée
scriptB interoge l'utilisateur puis lance scriptA avec les infos
recueillies.

Enfin tu me suggère de regarder tty ...
en effêt, en interactif il me donne un résultat variable du genre
/dev/ttyp5
alors que via cron, ça dit :
not a tty

J'ai souvent entendu parler de tty, mais j'ai jamais compris ce que
c'est au juste. <:o)


Un terminal, c'est en gros une paire de pipes (une entrée, et une sortie),
le noyau assurant un peu de discipline pour éviter que les divers programmes
lisant l'entrée et écrivant sur la sortie se mélangent trop. Il assure aussi
la gestion du ^C et le ^Z. Suivant le type de terminal, ce qui arrive dans
l'entrée, peut être fourni directement par le noyau (quand on est console,
le noyau transmet ce qu'on tape au clavier), ou par un programme (xterm,
sshd, ...). Et dualement, la sortie est affichée directement par le noyau ou
transmise à un programme.

En général, quand on utilise un shell interactif, c'est dans un terminal
(dès que tu ouvres un xterm, il alloue un terminal et lance le shell dedans
(c'est à dire, il dit au noyau que ce shell dépend du terminal, et il
connecte les entrées et sorties du shell avec celles du terminal)). Tandis
que cron n'alloue pas de terminal pour exécuter les commandes.

Est-ce que ces 2 solutions sont fiables ?
($TERM et tty) Ou faut-il me méfier ?


Le tty est certainement plus fiable que le $TERM. Mais moins que l'option
explicite avec une variable d'environnement ou un argument. À laquelle je
préfère le découpage.

Avatar
Luc.Habert.00__arjf
Damien Wyart :

Sur certains shells (bash, zsh, pour les autres je ne sais pas), la
variable $- contiendra un 'i' si on est en mode interactif.


Mais ce n'est pas ce qu'on veut ici. On veut détecter le type du shell
depuis lequel on a lancé le script, qui, lui, est de toutes manières exécuté
par un shell non interactif.

Avatar
Nicolas.MICHEL
Luc Habert wrote:

Non, au contraire. Tu te choisis un nom de variable qui ne conflicte avec
rien d'autre, et tu définis cette variable au moment d'appeller le script
(par exemple dans la crontab) lorsque tu ne veux pas de question.


Hi hi, je viens d'immaginer une solution et en te relisant je crois que
c'est exactement ce que tu me propose :
Dans la crontab, j'appelles mon script avec une option --quiet (-q).
De cette façon j'ai un seul script clairement interactif sauf si on
spécifies le contraire.
C'est une possibilité en effêt.
Mais c'est pas très neuneu-proof.

Créer 2 scripts, l'un pour le mode interactif et l'autre pour cron
m'ennuyes pour des raisons de débuggage


Pourquoi? La programmation modulaire, ça facilite le débugage, au contraire.
Je ne te dis pas de dupliquer le code.


En tentant de voir comment appliquer cette méthode à mon script je
m'apperçois que déjà au niveau de la conception, séparer les 2 modes
(verbose-interactif ou quiet-cronjob) simplifie les problèmes et les
rends plus clairs. De plus il est vrais que 2 scripts de 100 lignes sont
moins astreignants qu'un seul script de 200 lignes, ça je l'ai déjà
constaté.

et ça risque de paraitre complexe à mes collègues ...


Là, c'est toi qui les connais mieux que moi, c'est sûr.


Pas vraiment, je fais ça aussi pour de futurs collègues que je ne
connais pas encore, des apprentis qui arriveront bientôt, mon remplaçant
le jour où je parts à la retraite, ...
La seule donnée que tu ignores c'est que c'est pour du Mac et qu'il ne
faut pas trop en demander à un Macounet. Déjà faire un script shell,
c'est ôsé, je connais des "admin" mac GUI only.
Bon, sur les autres *nix c'est un peu pareil excepté que la mentalité
est de tirer l'utilisateur vers la connaissance de sa machine plutôt que
d'abaisser la machine à un fonctionnement "simpliste" mais neuneu-proof.

Mais je ne vois pas
ce qu'on peut trouver de complexe à :

scriptA avec liste d'arguments complète bien spécifiée
scriptB interoge l'utilisateur puis lance scriptA avec les infos
recueillies.


Quand on a l'habitude d'une souris à un seul bouton ... ;->

(xterm, sshd, ...)
[snip l'explication intéressante]


Une remarque à ce sujet
Connecté en ssh sur un client, j'ai un tty.
Si je place la commande directement dans "l'appel" ssh, pas de tty :
$ ssh -l toto 130.223.123.12 "tty"
not a tty

Donc c'est une des "failles" de cette méthode, configurer le script
requiert un tty. Bon, cette restriction me convient en fait.

Le tty est certainement plus fiable que le $TERM. Mais moins que l'option
explicite avec une variable d'environnement ou un argument. À laquelle je
préfère le découpage.


Je comprends ce que tu veux dire.
Je vais, dans un premier temps, écrire 2 scripts séparés.
C'est plus clair à écrire.
Mais je les appelerai dans le même shell (genre ". script2") plutôt que
par un appel de commande "standard". De cette façon je pourrai sans
autre placer le script 2 dans le script 1, avec juste un test "tty".

Merci beaucoup !! :)

--
Nicolas


Avatar
Luc.Habert.00__arjf
Nicolas MICHEL :

Une remarque à ce sujet
Connecté en ssh sur un client, j'ai un tty.
Si je place la commande directement dans "l'appel" ssh, pas de tty :
$ ssh -l toto 130.223.123.12 "tty"
not a tty

Donc c'est une des "failles" de cette méthode, configurer le script
requiert un tty.


Oui. Enfin cette manière d'utiliser ssh est plutôt faite pour des commandes
non interactives. Si tu veux lancer une commande interactive de la sorte, tu
peux rajouteur l'option « -t » pour demander au sshd d'allouer un terminal.

Avatar
Nicolas.MICHEL
Luc Habert wrote:

Nicolas MICHEL :

Une remarque à ce sujet
Connecté en ssh sur un client, j'ai un tty.
Si je place la commande directement dans "l'appel" ssh, pas de tty :
$ ssh -l toto 130.223.123.12 "tty"
not a tty

Donc c'est une des "failles" de cette méthode, configurer le script
requiert un tty.


Oui. Enfin cette manière d'utiliser ssh est plutôt faite pour des commandes
non interactives. Si tu veux lancer une commande interactive de la sorte, tu
peux rajouteur l'option « -t » pour demander au sshd d'allouer un terminal.


OK, merci :)


--
Nicolas


1 2