Comment puis-je vérifier dans bash si un shell s'exécute en mode interactif?

46

Comment savoir ~/.bashrcsi je cours en mode interactif ou, disons, en exécutant une commande sur ssh. Je veux éviter d’imprimer des séquences d’échappement ANSI .bashrcsi c’est la dernière.

Alex B
la source
Il est préférable de choisir d’imprimer ou non des séquences d’échappement selon la valeur $ TERM et non sur l’interactivité du shell. La variable identifie les capacités du terminal client qui est la partie qui interprète les séquences d'échappement.
yrk

Réponses:

53

Selon man bash:

PS1 est défini et $ - inclut i si bash est interactif, permettant à un script shell ou à un fichier de démarrage de tester cet état.

Pour que vous puissiez utiliser:

if [[ $- == *i* ]]
then
    do_interactive_stuff
fi

Aussi:

Lorsqu'un shell interactif qui n'est pas un shell de connexion est démarré, bash lit et exécute les commandes de /etc/bash.bashrc et ~ / .bashrc, si ces fichiers existent.

Donc, ~/.bashrcne provient que des coques interactives. Parfois, les personnes le recherchent ~/.bash_profileou ~/.profilece qui est incorrect car il interfère avec le comportement attendu. Si vous souhaitez simplifier la maintenance du code courant, vous devez utiliser un fichier séparé contenant le code commun et le source indépendamment des deux fichiers rc.

Il est préférable de ne pas générer de sortie de rcfichiers de connexion tels que ~/.bash_profileou sur stdout, ~/.profilecar cela pourrait nuire au bon fonctionnement de, rsyncpar exemple.

Dans tous les cas, il est toujours judicieux de tester l'interactivité, car une configuration incorrecte peut exister.

Dennis Williamson
la source
7
Notez que $ - peut contenir un i, pas nécessairement égal à lui. J'utilise[[ $- =~ i ]] && echo interactive
Alex Howansky le
1
@AlexHowansky: les astérisques dans le test d'égalité en font un test pour conteniri
Dennis Williamson
Oh wow, je ne les ai même pas remarquées, elles ressemblent à des guillemets sur mon moniteur. Il est peut-être temps d'augmenter la taille de la police. <vieux>
Alex Howansky
Parfois, les personnes le recherchent ~/.bash_profileou ~/.profilece qui est incorrect car il interfère avec le comportement attendu Right. Que pensez - vous de l' approvisionnement à ~/.bashrcpartir ~/.bash_login? Comme le shell de connexion n'a pas besoin d'être interactif, je suppose que c'est également incorrect.
Piotr Dobrogost
1
@PiotrDobrogost: Il s'agit d'une excellente discussion sur les fichiers de démarrage du shell.
Dennis Williamson
12

Utilisation:

if tty -s; then echo interactive; fi
sorin
la source
Ne semble pas fonctionner
Steven Shaw
cela ne semble pas fonctionner pour moi non plus, je pense que c'est la bonne réponse: stackoverflow.com/a/49064632/1223975
Alexander Mills
ceci vérifie la présence d'un ATS sur l'entrée standard; Bien que cela puisse être apparenté, ce n'est pas le même que le mode interactif du shell, qui est indiqué par le drapeau "-i" du shell.
yrk
Ne fonctionne pas. pourquoi les gens ont voté?
Setop
11

l' testoutil peut vérifier cela (depuis la page de manuel):

 -t FD          True if FD is opened on a terminal.

Vous pouvez donc utiliser par exemple:

 if [ -t 0 ] ; then
    echo stdin is a terminal
   .....
 fi

ou

if [ -t 1 ] ; then
    echo stdout is a terminal
 fi
utilisateur4514
la source
Nice et semble être portable entre les coquilles. TEST il bash <<< 'test -t 0 && echo Y || echo X'écrit Y, bash -c 'test -t 0 && echo Y || echo X'écritX
kyb
1
cela vérifie également que l'entrée standard est un TTY; bien que cela puisse être apparenté, ce n'est PAS le même que le mode interactif du shell, qui est demandé et indiqué par le drapeau "-i" du shell.
yrk
6

Je regarde généralement la sortie du programme tty.

Si vous êtes sur un tty, il vous dira sur quel tty vous êtes. Si vous n'êtes pas en mode interactif, il vous dira généralement quelque chose comme "pas un tty".

chris
la source
3
tty -s définira une valeur de retour de 0 si vous êtes sur un terminal ou 1 sinon sans vous donner de sortie. Vous pouvez l'utiliser comme 'if tty -s; alors _interactif; fi '
BillThor
Merci! Cela fait longtemps que je n'ai pas besoin de faire ce genre de chose et je suppose que j'ai oublié certains détails ...
chris
0

C'est comme ça que Red Hat le fait ... En devinant que c'est le moyen le plus rapide ...

if [ "$-#*i" == "$-" ]; then

Cela signifie obtenir les paramètres bash, effectuer une suppression de sous-chaîne, la plus courte possible, faire correspondre tout ce qui se situe entre le début et i. Puis vérifiez si c'est le même que les paramètres bash d'origine.

Vérifiez que vous avez bien fait votre travail en vous connectant à l'utilisateur à l'aide de sftp. Il échouera si des sessions non interactives sont en sortie.

Ray Foss
la source