¿Por qué un shebang necesita un camino?
Incorrecto
#!ruby
Correcto
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
El sistema operativo debe tener la información sobre la ruta de un comando registrado, y ¿por qué todavía espera que se le dé?
Probablemente para mantener el núcleo más simple. No creo que el núcleo busque su ruta para encontrar un ejecutable. Eso es manejado por la biblioteca C. #!
el procesamiento se realiza en el kernel, que no usa la biblioteca estándar de C.
Además, no creo que el núcleo tenga una noción de cuál es su camino. $PATH
es una variable de entorno, y solo los procesos tienen un entorno. El núcleo no lo hace. Supongo que podría acceder al entorno del proceso que hizo el ejecutivo, pero no creo que nada en el núcleo acceda a variables de entorno como esa.
Puede obtener la PATH
semántica de búsqueda mediante env
, por lo tanto:
#!/usr/bin/env ruby
tiene la semántica que le gustaría
#!ruby
La razón por la que depender 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 "modelo de dependencia secuencial" de los archivos binarios donde
/bin
contiene los ejecutables necesarios en el momento del arranque;/usr/bin
contiene los otros ejecutables utilizados por la instalación del sistema operativo;/usr/local/bin
contiene ejecutables instalados por el administrador del sistema que no forman parte del sistema operativo base.~/bin
contiene los propios ejecutables del usuario.Cada nivel no debe asumir la existencia de archivos binarios más adelante en la secuencia, que son más "aplicación" pero pueden depender de los archivos binarios anteriores, que son más "fundamentales". Y la variable PATH tiende a ejecutarse de aplicativa a fundamental, que es la dirección opuesta a la dependencia natural anterior.
Para ilustrar el problema, pregúntese qué sucede si una secuencia de comandos ~/bin
invoca una secuencia de comandos /usr/local/bin
que invoca a Ruby. ¿Debería ese script depender de la versión instalada del sistema operativo /usr/bin/ruby
o de la copia personal en la que el usuario tenga ~/bin/ruby
? PATH
la búsqueda proporciona la semántica impredecible asociada con el último (tal vez ~/bin/ruby
es un enlace simbólico roto), mientras que se abre camino en el camino hacia #!
el primero.
Realmente no hay ningún otro "sistema operativo ... independiente de la plataforma ... información sobre la ruta de un comando registrado", por lo que lo más simple es insistir en que la ruta se proporcione en el #!
.
Creo que es para que pueda especificar un intérprete alternativo si lo necesita o quiere. Por ejemplo:
#!/home/user/myrubyinterpreter
Más a menudo visto con scripts de shell:
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
ruby
, pero eso no le impide especificar/home/user/myrubyinterpreter
si lo deseaDel libro Classic Shell Scripting :
fuente
Hay otras razones, pero desde una perspectiva de seguridad, nunca quisiera que un script haga suposiciones sobre la ruta correcta. ¿Qué pasa si está mal y ejecuta el intérprete o intérprete de comandos incorrecto? ¿Uno que haya sido insertado por un usuario malicioso? ¿O qué sucede si se basa en un shell particular y se bloqueará si se usa el shell incorrecto?
Los usuarios pueden perder el tiempo con su ruta y romper cosas; no confíen en el usuario :-) He realizado numerosos ataques que dependen de que el usuario haga lo incorrecto con su ruta, generalmente obteniendo las cosas en el orden incorrecto, para que pueda subvertir Una llamada de guión normal.
Sí, sé que si ha escrito el guión usted mismo, puede afirmar con razón que ha resuelto su propio camino, pero un intérprete no puede tomar esas decisiones.
fuente
$PATH
. . Sin privilegios elevados, ¿quéLD_PRELOAD
pasa si se usa? PD Voto rechazado porque dar una advertencia falsa sobre seguridad es perjudicial para la seguridad.PATH
sea un vector de ataque y no haya tantos otros vectores de ataque que se deba repensar todo el enfoque?