Odpowiedzi:
Prawdopodobnie w celu uproszczenia jądra. Nie sądzę, aby jądro kiedykolwiek przeszukiwało twoją ścieżkę w celu znalezienia pliku wykonywalnego. Jest to obsługiwane przez bibliotekę C. #!
przetwarzanie odbywa się w jądrze, które nie korzysta ze standardowej biblioteki C.
Nie sądzę też, aby jądro miało pojęcie o twojej ścieżce. $PATH
jest zmienną środowiskową i tylko procesy mają środowisko. Jądro nie. Przypuszczam, że może on uzyskać dostęp do środowiska procesu, który wykonał exec, ale nie sądzę, aby cokolwiek w jądrze kiedykolwiek uzyskiwało dostęp do takich zmiennych środowiskowych.
Możesz uzyskać PATH
-semantykę wyszukiwania env
, więc:
#!/usr/bin/env ruby
ma semantykę, z której chcesz
#!ruby
Powodem, dla którego zależność PATH
nie jest uważana za dobrą praktykę, jest to, że skrypt nie może przyjmować żadnych założeń dotyczących zawartości zmiennej środowiskowej PATH, niszcząc „sekwencyjny model zależności” plików binarnych, w których
/bin
zawiera pliki wykonywalne potrzebne podczas rozruchu;/usr/bin
zawiera inne pliki wykonywalne używane podczas instalacji systemu operacyjnego;/usr/local/bin
zawiera pliki wykonywalne zainstalowane przez administratora systemu, które nie są częścią podstawowego systemu operacyjnego.~/bin
zawiera własne pliki wykonywalne użytkownika.Każdy poziom nie powinien zakładać istnienia plików binarnych w dalszej kolejności, które są bardziej „aplikacjami”, ale mogą polegać na plikach binarnych, które są bardziej „fundamentalne”. Zmienna PATH ma tendencję do działania od aplikacji do fundamentu, co jest odwrotnym kierunkiem do naturalnej zależności powyżej.
Aby zilustrować problem, zadaj sobie pytanie, co się stanie, jeśli skrypt ~/bin
wywołuje skrypt, /usr/local/bin
który wywołuje Ruby? Czy ten skrypt powinien zależeć od wersji zainstalowanej systemu operacyjnego /usr/bin/ruby
, czy od osobistej kopii, w której użytkownik ma ten plik ~/bin/ruby
? PATH
wyszukiwanie daje nieprzewidywalną semantykę związaną z tym drugim (być może ~/bin/ruby
jest zerwanym łączem symbolicznym), a pieczenie na ścieżce #!
daje to pierwsze.
Tak naprawdę nie ma innego niezależnego od platformy „systemu operacyjnego ... informacji dotyczących ścieżki zarejestrowanego polecenia”, więc najprościej jest nalegać na podanie ścieżki w #!
.
Wierzę, że tak, więc możesz określić alternatywnego tłumacza, jeśli potrzebujesz lub chcesz. Na przykład:
#!/home/user/myrubyinterpreter
Częściej spotykane ze skryptami powłoki:
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
Z książki Classic Shell Scripting :
Skrypty powłoki zwykle zaczynają się od
#! /bin/sh
. Użyj ścieżki do powłoki zgodnej z POSIX, jeśli nie jesteś/bin/sh
zgodny z POSIX. Istnieją również „gotchas” niskiego poziomu, na które należy uważać:
- Musisz znać pełną nazwę ścieżki do tłumacza, który chcesz uruchomić. Może to zapobiec przenośności między dostawcami, ponieważ różni dostawcy umieszczają rzeczy w różnych miejscach (np.
/bin/awk
Kontra/usr/bin/awk
).
Są inne powody, ale z punktu widzenia bezpieczeństwa nigdy nie chciałbym, aby skrypt przyjmował założenia dotyczące właściwej ścieżki. Co jeśli jest źle i uruchamia niewłaściwą powłokę lub interpretera? Ten, który został wstawiony przez złośliwego użytkownika? A co, jeśli opiera się na konkretnej powłoce i ulegnie awarii, jeśli zostanie użyta niewłaściwa powłoka?
Użytkownicy mogą zepsuć swoją ścieżkę i popsuć różne rzeczy - nie ufaj użytkownikowi :-) Przeprowadziłem wiele ataków, które polegają na tym, że użytkownik robi coś złego na swojej ścieżce - zwykle robi to w złej kolejności - więc mogę obalić normalne wywołanie skryptu.
Tak, wiem, że jeśli sam napisałeś skrypt, możesz słusznie twierdzić, że wytyczyłeś własną ścieżkę, ale tłumacz nie może podejmować tych decyzji.
$PATH
. . Bez podwyższonych uprawnień co się stanie, jeśli LD_PRELOAD
zostanie użyty? PS Przegłosowano, ponieważ fałszywe ostrzeżenie o bezpieczeństwie jest szkodliwe dla bezpieczeństwa.
PATH
wektor ataku jest niewystarczający, i że nie ma tak wielu wektorów ataku, że należy ponownie przemyśleć całe podejście?
ruby
, ale to nie powstrzymuje cię przed określeniem,/home/user/myrubyinterpreter
czy chcesz