Est-il possible qu'il existe un shell de connexion qui n'est pas interactif?


11

En interprétant cet organigramme

entrez la description de l'image ici

J'ai trouvé que dans man bash:

Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec l'option --login, il lit et exécute d'abord les commandes du fichier / etc / profile, si ce fichier existe.

Cela indique que les shells de connexion interactifs lisent /etc/profile(sans --noprofile)

En outre, les shells non interactifs avec l'option --loginlire/etc/profile

Cela semble laisser certains shells de connexion possibles (dans lesquels $0commence par a -) qui étant non interactifs (exécutez un script, peut-être aussi simple que date) peuvent ne pas lire (source) /etc/profile.

Pour confirmer ou infirmer cette idée:

J'ai d'abord essayé d'utiliser su -l -, qui démarre un shell de connexion avec un -comme premier caractère mais je n'arrive pas à le rendre non interactif (et à pouvoir présenter les tests pour le tester).

Appeler quelque chose comme

$ bash -c 'date' -bash

Ne signale pas être un shell de connexion (même si le premier caractère est un -).

Essayez ceci pour révéler le détail:

   $ bash -c 'echo "$0 $- ||$(shopt -p login_shell)||";date' -bash
      -bash hBc ||shopt -u login_shell||
      Fri Aug 19 06:32:31 EDT 2016

Le $0a -comme premier caractère, il n'y a pas i(interactif) dans la valeur de $-mais il n'est pas signalé comme login_shell(le -u). Dans ce cas, / etc / profile n'a pas été lu, mais je ne suis pas sûr que ce soit le bon test.


Il y a aussi la mention des «shells de connexion non interactifs rares» dans cette réponse sans être suffisamment précis pour cette question.


La conclusion de ce type est qu'il /etc/profileest toujours lu.

Lire le tableau récapitulatif: les shells de connexion interactifs et non interactifs lisent /etc/profile


Et, si les exemples de cette page sont corrects:

Some examples

$ su bob                   # interactive non-login shell
$ su - bob                 # interactive login shell
$ exec su - bob            # interactive login shell
$ exec su - bob -c 'env'   # non-interactive login shell
$ ssh bob@example.com      # interactive login shell, `~/.profile`
$ ssh bob@example.com env  # non-interactive non-login shell, `~/.bashrc`

Le test des exec su - bob -c 'env'rapports qui a /etc/profileété lu.


En bref:

Est-il possible d'avoir un shell de connexion non interactif (non appelé avec --login ou -l)?

Et si c'est vrai, lit-il le /etc/profilefichier?

Si ce qui précède est vrai, nous devons conclure que TOUS les shells de connexion [interactifs (ou non)] lisent / etc / profile (sans --noprofileoption).

Remarque: pour détecter que / etc / profile est en cours de lecture, ajoutez simplement au tout début du fichier cette commande:

echo "'/etc/profile' is being read"

Réponses:


2

Un shell de connexion non interactif est inhabituel, mais possible. Si vous démarrez le shell avec l'argument zeroth (qui est normalement le nom de l'exécutable) défini sur une chaîne commençant par a -, c'est un shell de connexion, qu'il soit interactif ou non.

$ ln -s /bin/bash ./-bash
$ echo 'shopt -p login_shell; echo $-' | HOME=/none PATH=.:$PATH -bash
shopt -s login_shell
hB

Votre tentative bash -c date -bashn'a pas fonctionné car cela ne dit pas au shell d'être un shell de connexion: l'argument zeroth ne l'est bashpas -bash. Après le démarrage de bash, il définit la variable $0à la -bashplace de l'argument zeroth, mais l'argument zeroth est ce qui compte.

Vous pouvez exécuter un shell de connexion non interactif avec su -lou su -, mais vous devez vous arranger pour que l'entrée standard ne soit pas un terminal tout en pouvant être autorisé (sans avoir à taper un mot de passe, ou faire en sorte que votre mot de passe soit au début de la contribution). Il peut être plus facile avec sudo: exécuter sudo truepour obtenir des informations d'identification de présence, puis pendant que les informations d'identification sont toujours valides, exécutez echo 'shopt -p login_shell; echo $-' | sudo -i.

Voir aussi Différence entre le shell de connexion et le shell sans connexion?


4

J'ai vu des environnements de connexion graphiques qui font:

exec "$SHELL" -l -c 'exec start-window-or-session-manager'

ou l'équivalent de:

exec -a "-$SHELL" "$SHELL" <<EOF
exec start-window-or-session-manager
EOF

Pour que le fichier d'initialisation de session (comme ~/.profilepour les shells de type Bourne (et ceux correspondants /etcpour certains)) soit lu et appliqué.

Le premier ne fonctionne pas avec tous les obus. -lest supporté par un grand nombre de shells, mais pas tous, et sur certains, comme csh/ tcsh, ne peut pas être utilisé avec -c. Cependant, le premier caractère de l' argv[0]être -est compris par tous les shells, car c'est ce qui loginsert à dire aux shells qu'ils sont des shells de connexion.

Dans le second cas, le stdin de ce shell est autre chose qu'un ttypériphérique ( <<est implémenté par un fichier régulier temporaire, ou un tube selon le shell), donc le shell n'est pas interactif (la définition de l'être interactif quand un humain interagit avec ça).


Le premier utilise l' --loginoption. Pour le second, si je exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"reçois (encodé en C qoutes) $'/etc/profile read\nshopt -s login_shell\nbash himBH'donc, c'est login mais c'est interactif. Nous avons besoin de connexion et non interactif . Qu'est-ce qui me manque?

@sorontar, avec <<<"$-", qui $-est développé par le shell appelant à cause des guillemets doubles. Le shell appelé n'est pas interactif car son stdin n'est pas un tty.
Stéphane Chazelas

Ah, oui, vous avez raison, monsieur. Cependant, en corrigeant l'erreur, nous pouvons le faire: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFpour obtenir cette confirmation: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'Donc, oui, un shell de connexion non interactif est possible, et il est toujours lu /etc/profile. Faut-il conclure que TOUS les shells de connexion sont lus /etc/profile?

ksh indique clairement qu'il s'agit d'un shell de connexion non interactif , essayez exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF:).

1
@sorontar, je pense que vous pouvez vous attendre à ce que la plupart des implémentations de shell lisent leurs fichiers d'initialisation de session lorsqu'ils sont appelés en tant que shell de connexion. Le choix dépend de l'implémentation et de la version du shell. Dans le cas de bash, la gestion des fichiers de démarrage est assez foireuse IMO, vous constaterez que certains systèmes l'ont corrigé pour avoir un comportement plus raisonnable en ajoutant encore plus de variation.
Stéphane Chazelas

3

Oui, des shells de connexion non interactifs sont possibles

$ head -1 /etc/profile
echo PROFILE BEING READ

$ echo echo hello | su -
PROFILE BEING READ
stdin: is not a tty
hello

$

C'est similaire à ce qui a simplifié: su -c 'echo hello' -. Ce qui, pour tester ce que nous avons besoin, devrait être écrit: su -c 'echo $0 $-; shopt -p login_shell' -pour obtenir cette réponse de confirmation (codé entre guillemets C): $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Cela confirme qu'un shell de connexion non interactif a été excuté et que, dans le processus, / etc / profile a été lu. Merci.

0

Est-il possible d'avoir un shell de connexion non interactif (non appelé avec --login ou -l)?

OUI.

$ (exec -a '-' bash -c 'shopt -q login_shell && echo login shell')

Cependant, notez que /etc/profilecela ne serait pas utilisé pour un shell de connexion non interactif à moins que l' --loginargument ne soit donné.

Un idiome commun qui appelle un shell de connexion non interactif est:

$ su - someuser -c somecommand

Mais cela souffre du fait qu'il /etc/profilene soit pas exécuté.

Il est possible de modifier ce comportement mais cela implique de personnaliser le code source de Bash au moment de la compilation en décommentant une option trouvée dans config-top.h :

/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */

Lorsque j'ai recherché cette suanomalie , j'ai constaté que d'autres obus, y compris zshet dashn'ont pas cet écart.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.