Ответы:
Вероятно, чтобы ядро было проще. Я не думаю, что ядро когда-либо ищет ваш путь, чтобы найти исполняемый файл. Это обрабатывается библиотекой C. #!
обработка выполняется в ядре, которое не использует стандартную библиотеку C.
Кроме того, я не думаю, что ядро имеет представление о вашем пути. $PATH
является переменной окружения, и только процессы имеют среду. Ядро нет. Я полагаю, что он может получить доступ к среде процесса, который выполнял exec, но я не думаю, что что-либо в настоящее время в ядре когда-либо обращается к таким переменным среды.
Вы можете получить PATH
семантику -searching используя env
, так:
#!/usr/bin/env ruby
имеет семантику вы хотели бы от
#!ruby
Причина, по которой зависимость PATH
не считается хорошей практикой, заключается в том, что сценарий не может делать предположений о содержимом переменной среды PATH, нарушая «модель последовательной зависимости» двоичных файлов, где
/bin
содержит исполняемые файлы, необходимые во время загрузки;/usr/bin
содержит другие исполняемые файлы, используемые при установке ОС;/usr/local/bin
содержит исполняемые файлы, установленные системным администратором, которые не являются частью базовой ОС.~/bin
содержит собственные исполняемые файлы пользователя.Каждый уровень не должен предполагать существование двоичных файлов позже в последовательности, которые являются более «прикладными», но могут полагаться на двоичные файлы ранее, которые являются более «фундаментальными». И переменная PATH имеет тенденцию работать от приложения к основному, что противоположно естественной зависимости выше.
Чтобы проиллюстрировать проблему, спросите себя, что произойдет, если скрипт in ~/bin
вызывает скрипт, /usr/local/bin
который вызывает Ruby? Должен ли этот сценарий зависеть от версии ОС, установленной в /usr/bin/ruby
, или от личной копии, в которой находится пользователь ~/bin/ruby
? PATH
поиск дает непредсказуемую семантику, связанную с последним (возможно, ~/bin/ruby
является неработающей символической ссылкой), в то время как поиск по пути к #!
первому дает.
На самом деле не существует какой-либо другой независимой от платформы «операционной системы ... информации о пути для зарегистрированной команды», поэтому самое простое - настаивать на пути, указанном в #!
.
Я считаю, что это так, вы можете указать альтернативного переводчика, если вам нужно или хотите. Например:
#!/home/user/myrubyinterpreter
Чаще всего встречается со скриптами оболочки:
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
Из классической книги сценариев Shell :
Сценарии оболочки обычно начинаются с
#! /bin/sh
. Используйте путь к POSIX-совместимой оболочке, если ваша/bin/sh
не POSIX-совместимая. Есть также некоторые «ошибки» низкого уровня, на которые стоит обратить внимание:
- Вы должны знать полный путь к интерпретатору, который будет запущен. Это может предотвратить переносимость между поставщиками, поскольку разные поставщики размещают вещи в разных местах (например, по
/bin/awk
сравнению с/usr/bin/awk
).
Есть и другие причины, но с точки зрения безопасности я бы никогда не хотел, чтобы скрипт делал предположения о правильном пути. Что, если это не так и работает не та оболочка или интерпретатор? Тот, который был вставлен злоумышленником? Или что, если он опирается на определенную оболочку и вылетит, если используется не та оболочка?
Пользователи могут возиться со своими путями и ломать вещи - не доверяйте пользователю :-) Я провел множество атак, которые основаны на том, что пользователь делает неправильные вещи со своим путем - обычно получая вещи в неправильном порядке - поэтому я могу подорвать нормальный вызов скрипта.
Да, я знаю, что если вы написали сценарий самостоятельно, вы можете совершенно справедливо утверждать, что вы выбрали свой собственный путь, но переводчик не может принимать эти решения.
$PATH
. , Без повышенных привилегий, что, если LD_PRELOAD
используется? PS Понижено, потому что ложное предупреждение о безопасности наносит ущерб безопасности.
PATH
существует вектор атаки, а других векторов атаки не так много, чтобы весь подход был переосмыслен?
ruby
, но это не помешает вам указать/home/user/myrubyinterpreter
, хотите ли вы