Шебанг и путь

22

Зачем шебангу нужен путь?

Неправильно

#!ruby

Правильный

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

Операционная система должна иметь информацию о пути для зарегистрированной команды, и почему она все еще ожидает, что она будет дана?

Савва
источник

Ответы:

22

Вероятно, чтобы ядро ​​было проще. Я не думаю, что ядро ​​когда-либо ищет ваш путь, чтобы найти исполняемый файл. Это обрабатывается библиотекой C. #!обработка выполняется в ядре, которое не использует стандартную библиотеку C.

Кроме того, я не думаю, что ядро ​​имеет представление о вашем пути. $PATHявляется переменной окружения, и только процессы имеют среду. Ядро нет. Я полагаю, что он может получить доступ к среде процесса, который выполнял exec, но я не думаю, что что-либо в настоящее время в ядре когда-либо обращается к таким переменным среды.

CJM
источник
5

Вы можете получить PATHсемантику -searching используя env, так:

#!/usr/bin/env ruby  

имеет семантику вы хотели бы от

#!ruby

Причина, по которой зависимость PATHне считается хорошей практикой, заключается в том, что сценарий не может делать предположений о содержимом переменной среды PATH, нарушая «модель последовательной зависимости» двоичных файлов, где

  1. /bin содержит исполняемые файлы, необходимые во время загрузки;
  2. /usr/bin содержит другие исполняемые файлы, используемые при установке ОС;
  3. /usr/local/bin содержит исполняемые файлы, установленные системным администратором, которые не являются частью базовой ОС.
  4. ~/bin содержит собственные исполняемые файлы пользователя.

Каждый уровень не должен предполагать существование двоичных файлов позже в последовательности, которые являются более «прикладными», но могут полагаться на двоичные файлы ранее, которые являются более «фундаментальными». И переменная PATH имеет тенденцию работать от приложения к основному, что противоположно естественной зависимости выше.

Чтобы проиллюстрировать проблему, спросите себя, что произойдет, если скрипт in ~/binвызывает скрипт, /usr/local/binкоторый вызывает Ruby? Должен ли этот сценарий зависеть от версии ОС, установленной в /usr/bin/ruby, или от личной копии, в которой находится пользователь ~/bin/ruby? PATHпоиск дает непредсказуемую семантику, связанную с последним (возможно, ~/bin/rubyявляется неработающей символической ссылкой), в то время как поиск по пути к #!первому дает.

На самом деле не существует какой-либо другой независимой от платформы «операционной системы ... информации о пути для зарегистрированной команды», поэтому самое простое - настаивать на пути, указанном в #!.

Чарльз Стюарт
источник
0

Я считаю, что это так, вы можете указать альтернативного переводчика, если вам нужно или хотите. Например:

#!/home/user/myrubyinterpreter

Чаще всего встречается со скриптами оболочки:

#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
Эндрю Ламберт
источник
4
Но зачем это нужно? Вы можете запустить ruby ​​напрямую ruby, но это не помешает вам указать /home/user/myrubyinterpreter, хотите ли вы
Michael Mrozek
Суть Майкла именно в том, что я спрашиваю.
Sawa
0

Из классической книги сценариев Shell :

Сценарии оболочки обычно начинаются с #! /bin/sh. Используйте путь к POSIX-совместимой оболочке, если ваша /bin/shне POSIX-совместимая. Есть также некоторые «ошибки» низкого уровня, на которые стоит обратить внимание:

  • Вы должны знать полный путь к интерпретатору, который будет запущен. Это может предотвратить переносимость между поставщиками, поскольку разные поставщики размещают вещи в разных местах (например, по /bin/awkсравнению с /usr/bin/awk).
Артуро Эрреро
источник
-2

Есть и другие причины, но с точки зрения безопасности я бы никогда не хотел, чтобы скрипт делал предположения о правильном пути. Что, если это не так и работает не та оболочка или интерпретатор? Тот, который был вставлен злоумышленником? Или что, если он опирается на определенную оболочку и вылетит, если используется не та оболочка?

Пользователи могут возиться со своими путями и ломать вещи - не доверяйте пользователю :-) Я провел множество атак, которые основаны на том, что пользователь делает неправильные вещи со своим путем - обычно получая вещи в неправильном порядке - поэтому я могу подорвать нормальный вызов скрипта.

Да, я знаю, что если вы написали сценарий самостоятельно, вы можете совершенно справедливо утверждать, что вы выбрали свой собственный путь, но переводчик не может принимать эти решения.

Рори Олсоп
источник
Это относится только к сценарию с повышенными привилегиями. И это необычно, потому что shebang и setxid не очень хорошо играют вместе, и есть куда больше беспокоиться, чем $PATH. , Без повышенных привилегий, что, если LD_PRELOADиспользуется? PS Понижено, потому что ложное предупреждение о безопасности наносит ущерб безопасности.
Жиль "ТАК - перестань быть злым"
Ваша точка зрения на setxid верна, однако это очень полезный вектор атаки, поэтому определенно не является ложным предупреждением
Rory Alsop
1
Не могли бы вы привести пример случая, когда PATHсуществует вектор атаки, а других векторов атаки не так много, чтобы весь подход был переосмыслен?
Жиль "ТАК - перестать быть злым"
@ Жиль - +1 у вас есть хорошая точка зрения, определенно, как будто это не работает, возможно, есть и другие способы, которые так же действительны, однако с точки зрения разбитых вещей, которые вы можете исправить, это легко.
Рори Олсоп