shebang et le path

Pourquoi un shebang a-t-il besoin d'un path?

Faux

#!ruby 

Correct

 #!/usr/local/bin/ruby #!/usr/bin/env ruby 

Le operating system devrait avoir les informations concernant le path pour une command enregistrée, et pourquoi s'attend-il encore à ce qu'il soit donné?

Probablement pour garder le kernel plus simple. Je ne pense pas que le kernel search votre path pour find un exécutable. C'est géré par la bibliothèque C. #! le traitement est fait dans le kernel, qui n'utilise pas la bibliothèque C standard.

En outre, je ne pense pas que le kernel a une idée de ce que votre path est. $PATH est une variable d'environnement, et seuls les process ont un environnement. Le kernel ne le fait pas. Je suppose qu'il pourrait accéder à l'environnement du process qui a fait l'exec, mais je ne pense pas que quelque chose actuellement dans le kernel accède à des variables d'environnement comme ça.

Vous pouvez get la sémantique de search PATH utilisant env , ainsi:

 #!/usr/bin/env ruby 

a la sémantique que vous souhaitez

 #!ruby 

La raison pour laquelle selon PATH n'est pas considérée comme une bonne pratique, c'est que le script ne peut pas faire d'hypothèses sur le contenu de la variable d'environnement PATH, rompant le «model de dépendance séquentielle» des binarys où

  1. /bin contient les exécutables nécessaires au démarrage;
  2. /usr/bin contient les autres exécutables utilisés par l'installation du operating system;
  3. /usr/local/bin contient les exécutables installés par l'administrateur système qui ne font pas partie du operating system de base.
  4. ~/bin contient les propres exécutables de l'user.

Chaque niveau ne devrait pas supposer l'existence de binarys plus tard dans la séquence, qui sont plus "application" mais peuvent countr sur les binarys plus tôt, qui sont plus "fondamentaux". Et la variable PATH tend à courir de l'application à la fondamentale, qui est la direction opposée à la dépendance naturelle ci-dessus.

Pour illustrer le problème, requestz-vous ce qui se passe si un script dans ~/bin invoque un script dans /usr/local/bin qui invoque Ruby? Ce script doit-il dépendre de la version du operating system installée sur /usr/bin/ruby , ou de la copy personnelle que l'user possède à ~/bin/ruby ? PATH search de PATH donne la sémantique imprévisible associée à cette dernière (peut-être ~/bin/ruby est un lien symbolique brisé), tout en prenant le path de #! donne le premier.

Il n'y a pas vraiment d'autre "operating system" indépendant de la plate-forme … des informations concernant le path pour une command enregistrée ", donc la chose la plus simple est d'insister sur le path fourni dans le #! .

Je crois que c'est ainsi que vous pouvez spécifier un autre interprète si vous en avez besoin ou que vous le souhaitez. Par exemple:

 #!/home/user/myrubyinterpreter 

Plus souvent vu avec des scripts shell:

 #!/bin/bash #!/bin/sh #!/bin/dash #!/bin/csh 

De Classic Shell Scripting livre:

Les scripts Shell commencent généralement par #! /bin/sh #! /bin/sh . Utilisez le path d'access à un shell compatible POSIX si votre /bin/sh n'est pas compatible POSIX. Il y a aussi quelques «pièges» de bas niveau à surveiller:

  • Vous devez connaître le path complet de l'interpréteur à exécuter. Cela peut empêcher la portabilité inter-fournisseurs, puisque différents fournisseurs placent les choses dans des endroits différents (par exemple, /bin/awk versus /usr/bin/awk ).

Il y a d'autres raisons, mais du sharepoint vue de la security, je ne voudrais jamais qu'un script fasse des hypothèses sur le bon path. Que se passe-t-il si cela ne fonctionne pas et que la mauvaise coquille ou l'interpréteur ne fonctionne pas correctement? Celui qui a été inséré par un user malveillant? Ou que se passe-t-il si elle s'appuie sur un shell particulier et va se planter si le mauvais shell est utilisé?

Les users risquent de perdre leur path et de casser des trucs – ne faites pas confiance à l'user 🙂 J'ai mené de nombreuses attaques qui font que l'user ne fait pas le bon path avec son path – en général les choses dans le mauvais ordre – un appel de script normal.

Oui, je sais que si vous avez écrit le script vous-même, vous pouvez affirmer à juste titre que vous avez réglé votre propre path, mais qu'un interprète ne peut pas prendre ces décisions.