Le bug shellshock dans bash fonctionne au moyen de variables d'environnement. Honnêtement, j'ai été surpris par le fait qu'il existe une telle fonctionnalité comme:
"transmission des définitions de fonction via env vars"
Par conséquent, cette question, même si elle n'est peut-être pas parfaitement formulée, est de demander un exemple ou un cas dans lequel il serait nécessaire d'avoir cette fonctionnalité?
Prime. Les autres coques zsh, dash etc. ont-elles également cette fonctionnalité?
bash
environment-variables
function
shellshock
l'humanité et la paix
la source
la source
parallel
obtient les définitions de fonction distribuées s'il invoque plusieurs instances bash. Si ce n'est pas de cette façon, il faudrait les écrire dans un fichier, que chaque instance invoquée lit et ensuite vous devez faire face à des problèmes comme quand ce fichier peut être supprimé..dot
sourcez le même fichier que l'ancien shell. thats comment son fait - et cela a du sens - ou vous alimentez le nouveau shell le fichier en entrée lors de l'exec
ing. une fois qu'il est lu une fois le fichier mis en cache par le noyau de toute façon.Réponses:
Lorsqu'un script appelle un autre script, les variables du script parent peuvent être exportées, puis elles seront visibles dans le script enfant. L'exportation de fonctions est une généralisation évidente: exportez la fonction du parent, rendez-la visible chez l'enfant.
L'environnement est le seul moyen pratique pour un processus de transmettre des données arbitraires à ses enfants. Les données doivent être rassemblées en chaînes qui ne contiennent pas d'octets nuls, ce qui n'est pas une difficulté pour les fonctions shell. Il existe d'autres méthodes potentielles, telles que des blocs de mémoire partagée ou des fichiers temporaires transmis via des descripteurs de fichiers, mais ceux-ci pourraient provoquer des problèmes avec des programmes intermédiaires qui ne savent pas quoi faire avec eux ou les fermeraient. Les programmes s'attendent à s'exécuter dans un environnement qui contient des variables qu'ils ne connaissent pas ou dont ils ne se soucient pas, donc ils ne vont pas les écraser ni les effacer.
Le choix d'utiliser le nom de la fonction comme nom de la variable d'environnement est étrange. D'une part, cela signifie qu'une variable exportée se heurte à une fonction exportée du même nom.
Les fonctions exportées sont une ancienne fonctionnalité. Des fonctions ont été ajoutées dans le shell Bourne dans SVR2 , et des fonctions exportées dans le shell version 8 publiées la même année (1984). Dans ce shell, les variables et les fonctions utilisaient le même espace de noms. Je ne sais pas comment a fonctionné l'exportation de fonctions. Le shell Heirloom est basé sur une variante Bourne qui a des fonctions mais ne les exporte pas.
ATT ksh prend soi-disant en charge l'exportation de fonctions, mais en regardant la source ou en jouant avec, je ne peux pas voir que c'est le cas, à partir de ksh93u.
Les clones du domaine public de Ksh (pdksh, mksh), dash et zsh ne prennent pas en charge les fonctions d'exportation.
la source
BASH_FUNC_f%%=() { echo hi }
. Pourquoi bash analyserait-il d'autres variables d'environnement? Pourquoi serait-il même analyséBASH_FUNC_g%%
lorsque je n'appelle quef
? (Apparemment, avant le shellshock, la variable d'environnement vient d'être appeléef
oug
- mais je me demande toujours pourquoig
aurait été analysée si je n'appelais jamaisg
dans mon script)f
, (1) de rechercher une fonction shell appeléef
, (2) de rechercher une variable d'environnement appeléef
et d'essayer de l'analyser, (3) de vérifier chaquePATH
composant d'un exécutable appeléf
. Comment l'analyse de chaque variable d'environnement en tant que code shell, au démarrage du shell, peut-elle sembler une conception moins compliquée?unset -f foo
, bash ne doit plus rechercher de définition de fonctionfoo
dans l'environnement), lors de la liste des fonctions (comment gérez-vousdeclare -f
autre que la lecture de toutes les variables d'environnement?) , et tout ce à quoi je ne pense pas. Votre conception ne semble plus facile parce que vous en avez omis la plupart. En revanche, tout faire au démarrage est un seul morceau de code et après cela, tout fonctionne.