Sur mon arche installer, /etc/bash.bashrc
et /etc/skel/.bashrc
contenir ces lignes:
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
Sur Debian, /etc/bash.bashrc
a:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
Et /etc/skel/.bashrc
:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Selon man bash
, cependant, les shells non interactifs ne lisent même pas ces fichiers:
When bash is started non-interactively, to run a shell script, for
example, it looks for the variable BASH_ENV in the environment, expands
its value if it appears there, and uses the expanded value as the name
of a file to read and execute. Bash behaves as if the following com‐
mand were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search for the file‐
name.
Si je comprends bien, les *.bashrc
fichiers ne seront lus que si BASH_ENV
est configuré pour les pointer. Ceci est quelque chose qui ne peut pas arriver par hasard et ne se produira que si quelqu'un a explicitement défini la variable en conséquence.
Cela semble empêcher la possibilité que les scripts attribuent .bashrc
automatiquement la source à un utilisateur BASH_ENV
, ce qui peut s'avérer utile. Etant donné que bash ne lira jamais ces fichiers lorsqu’ils ne sont pas exécutés de manière interactive, sauf indication contraire explicite, pourquoi les *bashrc
fichiers par défaut l’ autorisent-ils?
Réponses:
C'est une question que j'allais poster ici il y a quelques semaines. Comme terdon , j'ai compris que a
.bashrc
est uniquement destiné à des shells Bash interactifs; il ne devrait donc pas être nécessaire.bashrc
de vérifier s'il tourne dans un shell interactif. De manière confuse, toutes les distributions que j'utilise (Ubuntu, RHEL et Cygwin) avaient un type de vérification (testing$-
ou$PS1
) pour s'assurer que le shell actuel est interactif. Je n'aime pas la programmation culte de l'industrie du fret, alors je me suis efforcé de comprendre le but de ce code dans mon.bashrc
.Bash a un cas particulier pour les obus distants
Après avoir étudié le problème, j'ai découvert que les coques distantes sont traitées différemment. Bien que les shells non interactifs Bash n'exécutent normalement pas de
~/.bashrc
commandes au démarrage, un cas particulier est créé lorsque le shell est appelé par le démon de shell distant :Exemple
Insérez ce qui suit au début d’une télécommande
.bashrc
. (Si.bashrc
provient de.profile
ou.bash_profile
, désactivez-le temporairement pendant les tests):Exécutez les commandes suivantes localement:
i
in$-
indique que le shell n'est pas interactif .-
en$0
indique que la coquille n'est pas une coquille de connexion .Les fonctions shell définies dans la télécommande
.bashrc
peuvent également être exécutées:J'ai remarqué que l'
~/.bashrc
on ne sourced lorsqu'une commande est spécifiée comme argumentssh
. Cela a du sens: quandssh
est utilisé pour démarrer un shell de connexion normal,.profile
ou.bash_profile
est exécuté (et.bashrc
n’est recherché que si cela est fait explicitement par l’un de ces fichiers).Le principal avantage que je peux constater
.bashrc
lors de l’exécution d’une commande à distance (non interactive) est que les fonctions du shell peuvent être exécutées. Cependant, la plupart des commandes d'une commande typique.bashrc
ne sont pertinentes que dans un shell interactif. Par exemple, les alias ne sont pas développés sauf si le shell est interactif.Les transferts de fichiers à distance peuvent échouer
Ce n'est généralement pas un problème lorsque
rsh
oussh
sont utilisés pour démarrer un shell de connexion interactif ou lorsque des shells non interactifs sont utilisés pour exécuter des commandes. Cependant, cela peut être un problème pour des programmes tels quercp
,scp
etsftp
qui utilisent des shells distants pour transférer des données.Il s'avère que le shell par défaut de l'utilisateur distant (comme Bash) est lancé implicitement lors de l'utilisation de la
scp
commande. Il n'y a aucune mention de cela dans la page de manuel - seulement une mention quiscp
utilisessh
pour son transfert de données. Cela a pour conséquence que, si.bashrc
contient des commandes imprimant sur une sortie standard, les transferts de fichiers échoueront , par exemple, scp échouera sans erreur .Reportez-vous également à ce rapport de bogue Red Hat connexe datant d'il y a 15 ans: scp se brise lorsqu'il existe une commande echo dans / etc / bashrc (qui a finalement été fermée en tant que
WONTFIX
).Pourquoi
scp
etsftp
échouerSCP (copie sécurisée) et SFTP (protocole de transfert de fichier sécurisé) ont leurs propres protocoles pour les extrémités locale et distante afin d’échanger des informations sur le ou les fichiers en cours de transfert. Tout texte inattendu de l'extrémité distante est (à tort) interprété comme faisant partie du protocole et le transfert échoue. Selon une FAQ du livre d'escargot
Détails du protocole SCP
Pour les personnes intéressées par le fonctionnement de SCP, j'ai trouvé des informations intéressantes dans Fonctionnement du protocole SCP, notamment des informations sur Exécution de scp avec des profils de shell parlants du côté distant. :
Conclusion / TLDR
La plupart des instructions typiques
.bashrc
ne sont utiles que pour un shell interactif - pas lors de l'exécution de commandes distantes avecrsh
oussh
. Dans la plupart des situations de ce type, il n'est pas souhaitable de définir des variables de shell, des alias et des fonctions, et l'impression de texte sur une sortie standard est dangereuse pour le transfert de fichiers à l'aide de programmes tels quescp
ousftp
. Quitter après avoir vérifié que le shell actuel est non interactif est le comportement le plus sûr.bashrc
.la source
La page de manuel omet de mentionner que les
bash
sources.bashrc
pour les shells distants non interactifs, comme danshttp://git.savannah.gnu.org/cgit/bash.git/tree/shell.c#n1010
http://git.savannah.gnu.org/cgit/bash.git/tree/shell.c#n1050
la source
.bash_profile
présenterait le même comportement.rsh
(que je n'ai jamais utilisé) des sources~/.bashrc
? Et que, par extension, les distributions Linux le bloquentbash
juste au cas où quelqu'un essaierait de lancer un script avecrsh
?ssh server
ne devrait pas toucher.bashrc
car c'est un shell de connexion de toute façon. Non, sauf si votre système est l'un de ceux d'où provient ~ / .bashrc`~/.profile
. Etssh server command
ne devrait même pas faire ça. Certainement pas sur mon système.bash
source, pas larsh
source. :) Le commentaire s'appliquessh
également, il a été écrit il y a très longtemps. Voir la réponse mise à jour avec plus de source.echo
au sommet de/etc/bash.bashrc
et~/.bashrc
(avant les tests de shell interactifs), puis ssh dans la machine cible avecssh server hostname
et pendant l'hostname
exécution, je n'ai vu aucun de mes échos. Est-ce que monshell_level
(quoi que ce soit) n'est pas<2
?Par convention,
.bashrc
est l'endroit où l'utilisateur stocke la configuration de personnalisation pour le shell.Ces configurations personnalisées peuvent être des variables d’environnement, des alias, des invites de fantaisie. Avec un shell non interactif, ces choses courtes n'ont pas de sens. De plus, un shell non interactif peut être appelé dans de nombreux contextes. Vous n'êtes pas sûr que ces variables d'environnement puissent conduire à des cas de faux négatifs, voire à une vulnérabilité de la sécurité.
Un exemple le plus proche est un alias tel que:
Ensuite, il suspendra votre shell non interactif pour toujours.
Donc, la vérification s’effectue en haut
.bashrc
pour s’assurer que nous n’aurons pas de problèmes.Comme le shell peut être appelé en tant que shell de connexion non interactif , il est donc
*bashrc
inutile de recourir explicitement à la recherche de sources par blocs .Lorsque le réservoir a été appelé comme shell de connexion non interactif , sa source
/etc/profile
, la source puis la première trouvée dans~/.bash_profile
,~/.bash_login
et~/.profile
:Rien n'empêche ces fichiers de
.bashrc
s'auto- approvisionner . Le contrôle à l'intérieur.bashrc
est donc plus sûr et simplifie les choses.la source
*bashrc
fichier source . Ma question est la suivante: pourquoi différents fournisseurs de Linux essaient-ils d'empêcher explicitement les shells non interactifs de lire ces fichiers si ces fichiers ne sont de toute façon pas lus par des shells non interactifs?.bash_profile
, qui peut être source.bashrc
.$BASH_ENV
. Les deux*profile
et*bashrc
sont ignorés. Ou du moins, c'est ce que dit la page de manuel. Cependant, comme Mikel l’a montré, la page de manuel pourrait mentir.bash -l -c :
d'appeler un shell de connexion non interactif?--login
100 fois mais, apparemment, elle ne s'était jamais enregistrée. Merci!