Шебанг і стежка


22

Чому шебангу потрібна стежка?

Неправильно

#!ruby

Правильно

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

Операційна система повинна мати інформацію щодо шляху для зареєстрованої команди, і чому вона все ще очікує її надання?

Відповіді:


22

Можливо, щоб зробити ядро ​​простішим. Я не думаю, що ядро ​​ніколи не шукає ваш шлях, щоб знайти виконуваний файл. Цим керує бібліотека С. #!обробка проводиться в ядрі, яке не використовує стандартну бібліотеку C.

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


5

Ви можете отримати 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який викликає Рубі? Чи повинен цей скрипт залежати від встановленої версії ОС у /usr/bin/ruby, або від особистої копії, у якої трапляється користувач ~/bin/ruby? PATHпошук дає непередбачувану семантику, пов'язану з останньою (можливо ~/bin/ruby, це розірвана символічна ланка), тоді як випічка в шляху до #!дає першому.

Насправді не існує будь-якої іншої незалежної від платформи "операційної системи ... інформація щодо шляху для зареєстрованої команди", тому найпростіша річ - наполягати на наданому шляху в #!.


0

Я вважаю, що це так, що ви можете вказати альтернативного перекладача, якщо вам потрібно чи хочете. Наприклад:

#!/home/user/myrubyinterpreter

Частіше зустрічаються із скриптами оболонки:

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

4
Але чому це зробить це необхідним? Ви можете запускати рубін безпосередньо ruby, але це не заважає вам вказувати, /home/user/myrubyinterpreterчи хочете ви
Майкл Мрозек

Справа Майкла - це саме те, про що я прошу.
sawa

0

З класичної скриптової книги « Шелл» :

Сценарії оболонки зазвичай починаються з #! /bin/sh. Використовуйте шлях до оболонки, сумісної з POSIX, якщо ваша /bin/shсумісність не POSIX. Також є кілька низькорівневих "gotchas", на які слідкувати:

  • Ви повинні знати повне ім'я до інтерпретатора, який слід запустити. Це може запобігти переносимості між постачальниками, оскільки різні постачальники розміщують речі в різних місцях (наприклад, /bin/awkпроти /usr/bin/awk).

-2

Є й інші причини, але з точки зору безпеки я ніколи не хотів би, щоб сценарій робив припущення про правильний шлях. Що робити, якщо це неправильно, і він працює з неправильною оболонкою або інтерпретатором? Той, який вставив шкідливий користувач? Або що робити, якщо вона спирається на певну оболонку і вийде з ладу, якщо використовується неправильна оболонка?

Користувачі можуть заплутатися зі своїм шляхом і зламати речі - не довіряйте користувачеві :-) Я здійснив численні атаки, які покладаються на те, що користувач робить неправильний шлях своїм шляхом - як правило, виходить у неправильному порядку - тому я можу підривати звичайний скрипт-дзвінок.

Так, я знаю, якщо ви написали сценарій самостійно, ви цілком справедливо можете стверджувати, що ви розібралися у власному шляху, але перекладач не може приймати ці рішення.


Ця стурбованість стосується лише тих випадків, коли сценарій працює з підвищеними привілеями. І це нечасто, тому що шебанг і сетксид не грають добре разом, і турбуватися про це набагато більше $PATH. . Без підвищених пільг, що робити, якщо LD_PRELOADвони використовуються? PS Захищений, оскільки подання помилкового попередження про безпеку шкодить безпеці.
Жил "ТАК - перестань бути злим"

Ваша думка про setxid справедлива, проте це абсолютно корисний вектор атаки, тому точно не є помилковим попередженням
Rory Alsop

1
Чи можете ви навести приклад випадку, коли PATHє вектор атаки, а інших векторів нападу не так багато, щоб цілий підхід слід було продумати?
Жил "ТАК - перестань бути злим"

@Gilles - +1 у вас є хороша точка, безумовно, так як якщо це порушено, напевно, є й інші способи, які є такими ж дійсними, проте з точки зору зламаних речей, які ви можете виправити, це простий.
Rory Alsop
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.