shebang и path

Почему shebang нужен путь?

Неправильно

#!ruby 

Верный

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

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

5 Solutions collect form web for “shebang и path”

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

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

Вы можете получить семантику поиска PATH с помощью env , так что:

 #!/usr/bin/env ruby 

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

 #!ruby 

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

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

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

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

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

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

 #!/home/user/myrubyinterpreter 

Чаще всего встречаются сценарии оболочки:

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

Из книги Classic Scripting :

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

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

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

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

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

  • Заменить текущий процесс на его coprocess / child
  • Преобразование даты в оболочке bash
  • Как получить информацию о моих виртуальных рабочих столах через командную строку?
  • Преобразование и масштабирование большого количества png-изображений в jpeg
  • команда find также включает в себя текущий каталог в результате, который не требуется перемещать
  • Скрипт не выполняется в соответствии с ожиданием
  • Автоматически находить позицию, начиная с последней команды, запущенной в tmux
  • Solaris 10 не глобальных зон и rc-скриптов
  • Как обеспечить, чтобы исходящий трафик TCP / IP всегда использовал VPN, даже при использовании Wi-Fi?
  • Невозможно создать фоновый процесс
  • почему существует случайное поведение для фоновой работы?
  • bash - получить pid для скрипта, используя имя файла сценария
  • Linux и Unix - лучшая ОС в мире.