Différencier la connexion interactive et le shell non interactif sans connexion

25

J'essaie de différencier ces quatre termes de connexion, non-connexion, interactif et non interactif :

  • interactif - shell de connexion
  • interactif - shell sans connexion
  • non interactif - shell de connexion
  • non interactif - shell sans connexion

Si je comprends bien
interactif - shell sans connexion : démarrez le système, connectez-vous au système et ouvrez le terminal et
non interactif - shell de connexion : telnet au système et connectez-vous

Mais qu'en est-il d'un shell de connexion interactif?
Se connecte-t-il au système, ouvre-t-il un terminal virtuel et se connecte-t-il? et
non interactif - shell sans connexion, exécute-t-il un script automatisé dans crontab?

Marguerite
la source

Réponses:

38

La seule idée fausse réelle que vous semblez avoir concerne ce qui constitue un shell de connexion non interactif.

En bref (voir ici pour plus de détails), avec des exemples:

  • shell de connexion interactif: vous vous connectez à un ordinateur distant via, par exemple ssh. Alternativement, vous passez à un tty sur votre machine locale ( Ctrl+ Alt+ F1) et vous y connectez.

  • shell interactif sans connexion: ouvrez un nouveau terminal.

  • shell non interactif sans connexion: exécutez un script. Tous les scripts s'exécutent dans leur propre sous-shell et ce shell n'est pas interactif. Il s'ouvre uniquement pour exécuter le script et se ferme immédiatement une fois le script terminé.

  • shell de connexion non interactif: c'est extrêmement rare, et vous n'êtes pas disposé à le rencontrer. Une façon d'en lancer une est echo command | ssh server. Lorsqu'il sshest lancé sans commande (donc sshau lieu de celui ssh commandqui s'exécutera commandsur le shell distant), il démarre un shell de connexion. Si le stdinde sshn'est pas un tty, il démarre un shell non interactif. C'est pourquoi echo command | ssh serverlancera un shell de connexion non interactif. Vous pouvez également en démarrer un avec bash -l -c command.

Si vous souhaitez jouer avec cela, vous pouvez tester les différents types de shell comme suit:

  • Ce shell est-il interactif?

    Vérifiez le contenu de la $-variable. Pour les shells interactifs, il comprendra i:

    ## Normal shell, just running a command in a terminal: interacive
    $ echo $-
    himBHs
    ## Non interactive shell
    $ bash -c 'echo $-'
    hBc
  • S'agit-il d'un shell de connexion?

    Il n'y a pas de moyen portable de vérifier cela, mais, pour bash, vous pouvez vérifier si l' login_shelloption est définie:

    ## Normal shell, just running a command in a terminal: interacive
    $ shopt login_shell 
    login_shell     off
    ## Login shell; 
    $ ssh localhost
    $ shopt login_shell 
    login_shell     on

Pour mettre tout cela ensemble, voici un de chaque type de coque possible:

## Interactive, non-login shell. Regular terminal
$ echo $-; shopt login_shell
himBHs
login_shell     off

## Interactive login shell
$ bash -l
$ echo $-; shopt login_shell
himBHs
login_shell     on

## Non-interactive, non-login shell
$ bash -c 'echo $-; shopt login_shell'
hBc
login_shell     off

## Non-interactive login shell
$ echo 'echo $-; shopt login_shell' | ssh localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
hBs
login_shell     on
terdon
la source
Je veux effacer que 1) Pour moi, se connecter à gui signifie démarrer le système, se connecter au système et ouvrir le terminal 2) faire telnet ou ssh est un shell de connexion interactif signifie que l'exemple que j'ai donné non-interactive login shellest incorrect.
daisy
@daisy merci pour la clarification; réponse modifiée.
terdon
ok et gui est un shell interactif sans connexion non pertinent: ouvrez simplement un nouveau terminal localement ou à distance via telnet ou ssh
daisy
@daisy yep, ça sonne juste. Mais veuillez également lire attentivement la réponse de Muru car cela explique que, essentiellement, c'est une question de sémantique et n'affecte que les fichiers de démarrage lus par le shell. Voir également ici pour un aperçu encore plus complet des différents types de shell.
terdon
Les shells de connexion non interactifs ne sont pas si rares, par exemple git les utilise, IIRC.
quazgar
6

Essentiellement, que le shell soit connecté ou non, interactif ou non importe pour exactement une raison:

Les fichiers d'initialisation et les options par défaut définies varient selon qu'un shell est connecté ou non et interactif ou non.

De même, le fait qu'un shell soit connecté ou non, interactif ou non dépend uniquement de l' invocation utilisée - le nom de la commande exacte et les options.

Les deux propriétés sont par ailleurs orthogonales - qu'un shell soit connecté ou non n'a aucune incidence sur la détermination de son interactivité ou non.

Bash démarre un shell de connexion si l'une d'entre elles est vraie:

  • argv[0], le nom de la commande sous laquelle il a été invoqué commence par un -
  • l' -loption est spécifiée

De même, bash démarre un shell interactif si l'une d'entre elles est vraie:

  • il n'a pas été spécifié de fichier à exécuter (c'est-à-dire que la commande ne l'était pas bash some/file) ou de chaîne de commande à exécuter ( bash -c 'foo') (la condition réelle est un peu plus complexe, voir le manuel)
  • l' -ioption a été spécifiée

Notamment (et paradoxalement), ce dernier implique que bash -ic 'foo'démarre un shell interactif.

Donc, ce qui suit démarre une connexion, un shell interactif, même s'il n'a rien d'interactif et que l'invocation n'a rien à voir avec la connexion:

bash -lic true

La connexion via la console ou l'interface graphique démarre un shell de connexion (ou peut-être pas) est entièrement un effet du processus de connexion utilisant l'invocation appropriée.

Les conditions et les effets sont décrits en détail dans le manuel bash, section sur les fichiers de démarrage .


Une source majeure de confusion est qu'il existe une autre signification courante pour le shell "login":

Le shell de connexion d'un utilisateur est le shell défini dans l' passwdentrée de cet utilisateur (qui peut provenir de /etc/passwdLDAP ou d'une autre source).

Le loginprogramme, SSH, etc. démarre ce shell en tant que shell de connexion dans le sens que l'on entend dans le reste de la réponse - avec un début -dans le nom de la commande, généralement. Si vous vouliez être particulièrement déroutant, vous pourriez dire:

Certains processus de connexion démarrent le shell de connexion de l'utilisateur en tant que shell de connexion.

Notez que la connexion à l'interface graphique démarre un shell de connexion uniquement parce que les développeurs l'ont jugé pratique - LightDM exécute un script à la connexion qui n'est évidemment pas interactif et ne dépend certainement pas du shell de connexion de l'utilisateur (dans le deuxième sens). Cependant, ne dépendez pas du gestionnaire d'affichage qui démarre un shell de connexion - pas tous, et de Wayland et GNOME, le processus de connexion n'utilise pas du tout de scripts shell.

muru
la source
3

Shell de connexion:

Le premier processus qui s'exécute sous notre ID utilisateur lorsque nous nous connectons à une session. Le processus de connexion indique au shell de se comporter comme un shell de connexion avec une convention: en passant l'argument 0, qui est normalement le nom de l'exécutable du shell, avec un caractère «-» ajouté

Coque interactive:

Lit les commandes de l'entrée utilisateur sur un tty. Entre autres choses, un tel shell lit les fichiers de démarrage lors de l'activation, affiche une invite et active le contrôle des travaux par défaut. L'utilisateur peut interagir avec le shell. Un shell exécutant un script est toujours un shell non interactif.

Autrement dit: le shell interactif nécessite une entrée utilisateur, tandis que le shell non interactif est exécuté par des scripts et ne nécessite aucune entrée utilisateur.

George Udosen
la source
Les exemples donnés sont donc corrects.
daisy
Oui marguerite au bon endroit.
George Udosen
1
@daisy non! L'interface graphique n'a absolument rien à voir avec cela. Il s'agit de shells en ligne de commande, pas de shells graphiques (qui existent également mais sont une bête différente).
terdon
1
@George non, il y a deux erreurs: la connexion via l'interface graphique ne démarre pas un shell de connexion (ou tout autre type de shell pertinent) et la connexion à un système distant via telnet démarre un shell telnet, mais via ssh démarre une connexion interactive coquille.
terdon
1
@George en fait, je suis corrigé. Certains gestionnaires de connexion GUI peuvent démarrer un shell de connexion pour lire .profile(je pensais qu'ils se contentaient de source .profilemanuellement, mais je peux me tromper ).
terdon
0

Je voudrais mentionner que vous pouvez démarrer un shell de connexion interactif en:

  1. exécuter sudo /bin/loginet saisir vos informations d'identification
  2. exécution exec -l /bin/bash
  3. exécution su -
  4. et comme les réponses ci-dessus, en utilisant ssh et en vous connectant à une machine distante

En outre, vous pouvez vérifier (en bash) si le shell est connecté en tapant echo $0et si la sortie commence par un tiret -, alors c'est un shell de connexion.

SantaXL
la source