shebang e percorso


22

Perché uno shebang ha bisogno di un percorso?

Sbagliato

#!ruby

Corretta

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

Il sistema operativo dovrebbe disporre delle informazioni relative al percorso di un comando registrato e perché si aspetta ancora che venga fornito?

Risposte:


22

Probabilmente per semplificare il kernel. Non credo che il kernel abbia mai cercato il tuo percorso per trovare un eseguibile. Questo è gestito dalla biblioteca C. #!l'elaborazione viene eseguita nel kernel, che non utilizza la libreria C standard.

Inoltre, non penso che il kernel abbia un'idea di quale sia il tuo percorso. $PATHè una variabile di ambiente e solo i processi hanno un ambiente. Il kernel no. Suppongo che potrebbe accedere all'ambiente del processo che ha eseguito il exec, ma non credo che nulla attualmente nel kernel acceda mai a variabili di ambiente del genere.


5

Puoi ottenere la PATHsemantica di ricerca usando env, quindi:

#!/usr/bin/env ruby  

ha la semantica da cui vorresti

#!ruby

La ragione per cui, a seconda di ciò, PATHnon è considerata una buona pratica, è che lo script non può fare ipotesi sul contenuto della variabile d'ambiente PATH, rompendo il "modello di dipendenza sequenziale" dei binari in cui

  1. /bin contiene gli eseguibili necessari all'avvio;
  2. /usr/bin contiene gli altri eseguibili utilizzati dall'installazione del sistema operativo;
  3. /usr/local/bin contiene eseguibili installati dall'amministratore di sistema che non fanno parte del sistema operativo di base.
  4. ~/bin contiene i file eseguibili dell'utente.

Ogni livello non dovrebbe assumere l'esistenza di binari più avanti nella sequenza, che sono più "applicazioni" ma possono fare affidamento su binari precedenti, che sono più "fondamentali". E la variabile PATH tende ad andare dall'applicazione al fondamentale, che è la direzione opposta alla dipendenza naturale sopra.

Per illustrare il problema, chiediti cosa succede se una sceneggiatura ~/bininvoca una sceneggiatura /usr/local/binche invoca Ruby? Lo script dovrebbe dipendere dalla versione installata del SO /usr/bin/rubyo dalla copia personale in cui si trova l'utente ~/bin/ruby? PATHla ricerca fornisce la semantica imprevedibile associata a quest'ultima (forse ~/bin/rubyè un collegamento simbolico interrotto), mentre si infila nel percorso per #!dare la prima.

In realtà non esistono altri "sistemi operativi ... informazioni indipendenti dalla piattaforma relativi al percorso per un comando registrato", quindi la cosa più semplice è insistere sul percorso fornito nel file #!.


0

Credo che sia così che tu possa specificare un interprete alternativo se ne hai bisogno o vuoi. Per esempio:

#!/home/user/myrubyinterpreter

Più spesso visto con script di shell:

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

4
Ma perché ciò lo renderebbe necessario? Puoi eseguire ruby ​​direttamente con ruby, ma ciò non ti impedisce di specificare /home/user/myrubyinterpreterse vuoi
Michael Mrozek

Il punto di Michael è esattamente quello che sto chiedendo.
sawa,

0

Dal libro di scripting Shell classico :

Gli script Shell in genere iniziano con #! /bin/sh. Utilizzare il percorso di una shell conforme a POSIX se /bin/shnon si è conformi a POSIX. Ci sono anche alcuni "gotchas" di basso livello a cui prestare attenzione:

  • Devi conoscere il percorso completo per l'interprete da eseguire. Ciò può impedire la portabilità tra venditori, poiché fornitori diversi collocano le cose in luoghi diversi (ad es. /bin/awkContro /usr/bin/awk).

-2

Ci sono altre ragioni, ma dal punto di vista della sicurezza non vorrei che uno script facesse ipotesi sul percorso corretto. Che cosa succede se è sbagliato ed esegue la shell o l'interprete sbagliati? Uno che è stato inserito da un utente malintenzionato? O cosa succede se si basa su una particolare shell e si schianta se viene utilizzata la shell sbagliata?

Gli utenti possono scherzare con il loro percorso e rompere le cose - non fidarti dell'utente :-) Ho condotto numerosi attacchi che si basano sull'utente che fa la cosa sbagliata con il suo percorso - di solito portando le cose nell'ordine sbagliato - così posso sovvertire una normale chiamata di script.

Sì, so che se hai scritto la sceneggiatura da solo puoi giustamente affermare di aver risolto il tuo percorso, ma un interprete non può prendere quelle decisioni.


Questa preoccupazione si applica solo se lo script è in esecuzione con privilegi elevati. E questo è raro, perché shebang e setxid non giocano bene insieme, e c'è molto di più di cui preoccuparsi $PATH. . Senza privilegi elevati, cosa succede se LD_PRELOADviene utilizzato? PS Downvoted perché dare un falso avvertimento sulla sicurezza è dannoso per la sicurezza.
Gilles 'SO- smetti di essere malvagio' il

Il tuo punto su setxid è valido, tuttavia è un vettore di attacco perfettamente utile, quindi sicuramente non è un falso avvertimento
Rory Alsop

1
Potresti dare un esempio di un caso in cui si PATHtrova un vettore di attacco e non ci sono così tanti altri vettori di attacco che l'intero approccio dovrebbe essere ripensato?
Gilles 'SO- smetti di essere malvagio' il

@Gilles - +1 hai un buon punto, sicuramente, come se questo fosse rotto ci sono probabilmente altri modi in cui sono altrettanto validi, tuttavia in termini di cose rotte che puoi risolvere, questo è facile.
Rory Alsop,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.