Відповіді:
Можливо, щоб зробити ядро простішим. Я не думаю, що ядро ніколи не шукає ваш шлях, щоб знайти виконуваний файл. Цим керує бібліотека С. #!
обробка проводиться в ядрі, яке не використовує стандартну бібліотеку C.
Крім того, я не думаю, що ядро не має поняття про те, яким є ваш шлях. $PATH
є змінною середовища, і лише процеси мають середовище. Ядро ні. Я припускаю, що він може отримати доступ до середовища процесу, який робив exec, але я не думаю, що в даний момент ядро ніколи не отримує таких змінних середовищ.
Ви можете отримати PATH
дослідницьку семантику, використовуючи env
, таким чином:
#!/usr/bin/env ruby
має семантику, від якої ви б хотіли
#!ruby
Причиною того, що залежно від того PATH
, що не вважається хорошою практикою, є те, що сценарій не може робити припущень щодо змісту змінної середовища PATH, порушуючи "послідовну модель залежності" бінарних файлів, де
/bin
містить виконавчі файли, необхідні під час завантаження;/usr/bin
містить інші виконувані файли, використовувані при встановленні ОС;/usr/local/bin
містить виконавчі файли, встановлені системним адміністратором, які не входять до базової ОС.~/bin
містить власні виконувані файли користувача.Кожен рівень не повинен припускати існування бінарних файлів пізніше в послідовності, які є більш «застосувальними», але можуть покладатися на бінарні файли раніше, які є більш «фундаментальними». І змінна PATH має тенденцію переходити від застосовної до фундаментальної, що є протилежним напряму природній залежності вище.
Щоб проілюструвати проблему, запитайте себе, що станеться, якщо сценарій ~/bin
викликає сценарій, /usr/local/bin
який викликає Рубі? Чи повинен цей скрипт залежати від встановленої версії ОС у /usr/bin/ruby
, або від особистої копії, у якої трапляється користувач ~/bin/ruby
? PATH
пошук дає непередбачувану семантику, пов'язану з останньою (можливо ~/bin/ruby
, це розірвана символічна ланка), тоді як випічка в шляху до #!
дає першому.
Насправді не існує будь-якої іншої незалежної від платформи "операційної системи ... інформація щодо шляху для зареєстрованої команди", тому найпростіша річ - наполягати на наданому шляху в #!
.
Я вважаю, що це так, що ви можете вказати альтернативного перекладача, якщо вам потрібно чи хочете. Наприклад:
#!/home/user/myrubyinterpreter
Частіше зустрічаються із скриптами оболонки:
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
З класичної скриптової книги « Шелл» :
Сценарії оболонки зазвичай починаються з
#! /bin/sh
. Використовуйте шлях до оболонки, сумісної з POSIX, якщо ваша/bin/sh
сумісність не POSIX. Також є кілька низькорівневих "gotchas", на які слідкувати:
- Ви повинні знати повне ім'я до інтерпретатора, який слід запустити. Це може запобігти переносимості між постачальниками, оскільки різні постачальники розміщують речі в різних місцях (наприклад,
/bin/awk
проти/usr/bin/awk
).
Є й інші причини, але з точки зору безпеки я ніколи не хотів би, щоб сценарій робив припущення про правильний шлях. Що робити, якщо це неправильно, і він працює з неправильною оболонкою або інтерпретатором? Той, який вставив шкідливий користувач? Або що робити, якщо вона спирається на певну оболонку і вийде з ладу, якщо використовується неправильна оболонка?
Користувачі можуть заплутатися зі своїм шляхом і зламати речі - не довіряйте користувачеві :-) Я здійснив численні атаки, які покладаються на те, що користувач робить неправильний шлях своїм шляхом - як правило, виходить у неправильному порядку - тому я можу підривати звичайний скрипт-дзвінок.
Так, я знаю, якщо ви написали сценарій самостійно, ви цілком справедливо можете стверджувати, що ви розібралися у власному шляху, але перекладач не може приймати ці рішення.
$PATH
. . Без підвищених пільг, що робити, якщо LD_PRELOAD
вони використовуються? PS Захищений, оскільки подання помилкового попередження про безпеку шкодить безпеці.
PATH
є вектор атаки, а інших векторів нападу не так багато, щоб цілий підхід слід було продумати?
ruby
, але це не заважає вам вказувати,/home/user/myrubyinterpreter
чи хочете ви