Réponses:
Probablement pour garder le noyau plus simple. Je ne pense pas que le noyau recherche jamais votre chemin pour trouver un exécutable. Cela est géré par la bibliothèque C. #!
le traitement est effectué dans le noyau, qui n'utilise pas la bibliothèque C standard.
De plus, je ne pense pas que le noyau ait une idée de votre chemin. $PATH
est une variable d'environnement et seuls les processus ont un environnement. Le noyau ne fonctionne pas. Je suppose qu'il pourrait accéder à l'environnement du processus qui a fait l'exec, mais je ne pense pas que quoi que ce soit actuellement dans le noyau accède à des variables d'environnement comme ça.
Vous pouvez obtenir PATH
une sémantique de recherche à l'aide de env
:
#!/usr/bin/env ruby
a la sémantique que vous souhaitez
#!ruby
La raison pour laquelle le PATH
fait de ne pas être considéré comme une bonne pratique est que le script ne peut faire aucune hypothèse sur le contenu de la variable d'environnement PATH, brisant le "modèle de dépendance séquentielle" des binaires où
/bin
contient les exécutables nécessaires au démarrage;/usr/bin
contient les autres exécutables utilisés par l'installation du système d'exploitation;/usr/local/bin
contient des exécutables installés par l'administrateur système qui ne font pas partie du système d'exploitation de base.~/bin
contient les propres exécutables de l'utilisateur.Chaque niveau ne doit pas supposer l'existence de binaires plus tard dans la séquence, qui sont plus "d'application" mais peuvent s'appuyer sur des binaires plus tôt, qui sont plus "fondamentaux". Et la variable PATH a tendance à aller de l'application à la fondamentale, qui est la direction opposée à la dépendance naturelle ci-dessus.
Pour illustrer le problème, demandez-vous ce qui se passe si un script dans ~/bin
invoque un script /usr/local/bin
qui invoque Ruby? Ce script doit-il dépendre de la version du système d'exploitation installée sur /usr/bin/ruby
, ou de la copie personnelle que l'utilisateur possède sur ~/bin/ruby
? PATH
la recherche donne la sémantique imprévisible associée à celle-ci (peut ~/bin/ruby
- être est un lien symbolique brisé), tandis que la cuisson dans le chemin #!
donne à la première.
Il n'y a pas vraiment d'autre "système d'exploitation ... indépendant de la plate-forme ... d'informations concernant le chemin pour une commande enregistrée", donc la chose la plus simple est d'insister sur le chemin fourni dans le #!
.
Je pense que c'est pour que vous puissiez spécifier un autre interprète si vous en avez besoin ou si vous le souhaitez. Par exemple:
#!/home/user/myrubyinterpreter
Plus souvent vu avec les scripts shell:
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
Extrait du livre Classic Shell Scripting :
Les scripts shell commencent généralement par
#! /bin/sh
. Utilisez le chemin d'accès à un shell compatible POSIX si votre/bin/sh
n'est pas compatible POSIX. Il existe également des "pièges" de bas niveau à surveiller:
- Vous devez connaître le chemin d'accès complet à l'interpréteur à exécuter. Cela peut empêcher la portabilité entre les fournisseurs, car différents fournisseurs placent les choses à différents endroits (par exemple, par
/bin/awk
rapport à/usr/bin/awk
).
Il y a d'autres raisons, mais du point de vue de la sécurité, je ne voudrais jamais qu'un script fasse des hypothèses sur le chemin correct. Que se passe-t-il s'il est incorrect et qu'il exécute le mauvais interpréteur de commandes ou interpréteur? Celui qui a été inséré par un utilisateur malveillant? Ou que se passe-t-il s'il repose sur un shell particulier et se bloque si le mauvais shell est utilisé?
Les utilisateurs peuvent jouer avec leur chemin et casser des trucs - ne faites pas confiance à l'utilisateur :-) J'ai mené de nombreuses attaques qui reposent sur le fait que l'utilisateur fait la mauvaise chose avec son chemin - obtenant généralement les choses dans le mauvais ordre - afin que je puisse subvertir un appel de script normal.
Oui, je sais que si vous avez écrit le script vous-même, vous pouvez à juste titre affirmer que vous avez réglé votre propre chemin, mais un interprète ne peut pas prendre ces décisions.
$PATH
. . Sans privilèges élevés, que faire si LD_PRELOAD
est utilisé? PS a voté car donner un faux avertissement sur la sécurité est préjudiciable à la sécurité.
PATH
y a un vecteur d'attaque et où il n'y a pas tant d'autres vecteurs d'attaque que toute l'approche devrait être repensée?
ruby
, mais cela ne vous empêche pas de spécifier/home/user/myrubyinterpreter
si vous voulez