2016-10-11 2 views
5

Si, quand j'exécute un script, j'utilise LD_PRELOAD pour désigner une bibliothèque à précharger, je trouve que la bibliothèque n'est en fait préchargée que si le script a une ligne shebang. Par exemple, étant donné ce script:Pourquoi LD_PRELOAD ne prend-il pas effet avec des scripts n'ayant pas de shebang?

# Not a shebang 
echo Hello 

et cette commande:

LD_PRELOAD=/path/to/preload_me.so ./script.sh 

le script est exécuté sans la bibliothèque étant chargée du tout, que je peux suivre par les effets (non) de son initialisation code.

D'autre part, si j'ajoute une ligne de tralala:

#!/bin/sh 
echo Hello 

... alors la bibliothèque est chargée quand je lance le script via la même commande. Il ne semble pas important de savoir quel interprète est spécifié; certainement, je peux également utiliser /bin/bash ou tout autre sh -famille que j'ai essayé.

Pourquoi existe-t-il une différence, et existe-t-il un moyen de garantir qu'une bibliothèque donnée est préchargée avant une commande shell simple donnée, quelle que soit la commande?

(Adapté de another question dont l'auteur résisté à la question étant formulée en ces termes.)

Répondre

6

(Adapté de ma réponse à l'autre question fait référence.)

Il est essentiel de comprendre que LD_PRELOAD variable n'a pas signification particulière au système d'exploitation ou à la coque. Il a un sens et un effet - s'il en a du tout - seulement en conjonction avec le lieur dynamique. Si l'éditeur de liens dynamique n'est pas activé, alors LD_PRELOAD est juste une autre variable dans l'environnement. De même si l'éditeur de liens dynamique ne reconnaît pas cette variable (comme sur OS X, par exemple).

Il est également essentiel de comprendre que lors de l'exécution d'une commande dont le nom correspond à un fichier qui n'est pas dans un format exécutable mais qui contient une ligne shebang, l'interpréteur spécifié est exécuté, même s'il s'agit du shell lui-même. Si l'interpréteur est un binaire ELF, cela engage le lieur dynamique. D'un autre côté, s'il n'y a pas de ligne shebang, bash exécute le contenu du fichier dans un environnement de sous-shell, ce qui ne nécessite pas l'engagement du lieur dynamique; à la place, le shell ne fait que fourchonner. D'autres obus pourraient ou ne pourraient pas faire la même chose.

Il est également important de reconnaître que des formats exécutables autres que ELF existent. Il est peu probable que vous rencontriez un tel système binaire sur un système moderne ELF, mais vous ne devriez pas exclure cette possibilité.

Ligne de fond: il n'y a aucun moyen de garantir qu'une bibliothèque dynamique donnée sera préchargée dans l'espace de traitement d'une commande shell arbitraire exécutée via bash ou un autre shell choisi par l'utilisateur. Si vous avez besoin d'une bibliothèque préchargée pour n'importe quelle commande arbitraire, vous devez contrôler l'environnement d'exécution beaucoup plus strictement, peut-être en fournissant un shell personnalisé et peut-être aussi un éditeur de liens dynamique personnalisé.

+2

C'est une bonne réponse, mais je pense que vous devriez préciser qu'elle s'applique spécifiquement à 'bash' (et probablement à d'autres shells).' Dash' ne semble pas le faire, par exemple. (Il exécute le script, mais la précharge prend effet.Tout ce que Posix dit est "le shell doit exécuter une commande équivalente à l'invocation d'un shell avec le chemin d'accès résultant de la recherche en tant que premier opérande", ce qui pourrait s'appliquer à l'un ou l'autre comportement. (Test rapide sur mon système: préchargement de zsh, ksh ne marche pas.) – rici

+0

@rici, la réponse dit explicitement que * 'bash' * forks au lieu d'executer un nouveau shell, mais j'ai quand même ajouté une clarification. –