shebang y path

¿Por qué un shebang necesita un path?

Incorrecto

#!ruby 

Correcto

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

El sistema operativo debe tener la información con respecto a la ruta para un command registrado, y ¿por qué todavía espera que se le dé?

Probablemente para mantener el kernel más simple. No creo que el kernel busque su ruta para encontrar un ejecutable. Eso es manejado por la biblioteca C. #! el procesamiento se realiza en el kernel, que no utiliza la biblioteca C estándar.

Además, no creo que el núcleo tenga una noción de cuál es tu path. $PATH es una variable de entorno, y solo los processs tienen un entorno. El kernel no. Supongo que podría acceder al entorno del process que hizo el ejecutivo, pero no creo que nada en el kernel tenga acceso a variables de entorno como esa.

Puede get semántica de búsqueda PATH utilizando env , de modo que:

 #!/usr/bin/env ruby 

tiene la semántica que le gustaría de

 #!ruby 

La razón por la que dependiendo de PATH no se considera una buena práctica es que el script no puede hacer suposiciones sobre el contenido de la variable de entorno PATH, rompiendo el "model de dependencia secuencial" de los binarys donde

  1. /bin contiene los ejecutables necesarios en el momento del arranque;
  2. /usr/bin contiene los otros ejecutables utilizados por la installation del sistema operativo;
  3. /usr/local/bin contiene ejecutables instalados por el administrador del sistema que no son parte del sistema operativo base.
  4. ~/bin contiene los propios ejecutables del usuario.

Cada nivel no debe asumir la existencia de binarys más adelante en la secuencia, que son más de "aplicación", pero pueden basarse en binarys anteriores, que son más "fundamentales". Y la variable PATH tiende a ejecutarse desde la aplicación hasta la fundamental, que es la dirección opuesta a la dependencia natural anterior.

Para ilustrar el problema, pregúntese qué sucede si un script en ~/bin invoca un script en /usr/local/bin que invoca a Ruby. ¿Debería esa secuencia de commands depender de la versión instalada del sistema operativo en /usr/bin/ruby , o en la copy personal que el usuario tiene en ~/bin/ruby ? PATH búsqueda de PATH proporciona la semántica impnetworkingecible asociada con este último (tal vez ~/bin/ruby es un enlace simbólico roto), mientras se hornea en el path hacia #! da el primero.

No existe realmente ningún otro "sistema operativo … independiente de la plataforma … información sobre la ruta de un command registrado", así que lo más simple es insistir en el path que se proporciona en el #! .

Creo que eso es para que pueda especificar un intérprete alternativo si lo necesita o desea. Por ejemplo:

 #!/home/user/myrubyinterpreter 

Más a menudo visto con scripts de shell:

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

Desde el libro de scripting Classic Shell :

Los scripts de Shell normalmente comienzan con #! /bin/sh #! /bin/sh . Utilice la ruta de acceso a un shell compatible con POSIX si su /bin/sh no es compatible con POSIX. También hay algunos "errores" de bajo nivel para tener en count:

  • Debe conocer la ruta completa del intérprete que se ejecutará. Esto puede evitar la portabilidad entre proveedores, ya que los diferentes proveedores ponen las cosas en diferentes lugares (por ejemplo, /bin/awk versus /usr/bin/awk ).

Hay otras razones, pero desde una perspectiva de security, nunca me gustaría que un script haga suposiciones sobre la ruta correcta. ¿Qué sucede si está mal y ejecuta el shell o el intérprete incorrectos? ¿Uno que ha sido insertado por un usuario malicioso? ¿O qué pasa si se basa en un caparazón en particular y se bloqueará si se utiliza el armazón incorrecto?

Los usuarios pueden perder el rumbo y romper cosas. No confíes en el usuario 🙂 He llevado a cabo numerosos ataques que dependen de que el usuario haga lo incorrecto en su path, por lo general, haciendo las cosas en el order incorrecto, para que pueda subvertir una llamada de secuencia de commands normal.

Sí, sé que si usted mismo ha escrito el guión, puede afirmar con razón que ha resuelto su propio path, pero un intérprete no puede tomar esas decisiones.