Perché non usare shebang senza percorso?


Risposte:


20

La ricerca PATH è una caratteristica della libreria C standard nello spazio utente, così come le variabili di ambiente in generale. Il kernel non vede le variabili di ambiente tranne quando passa sopra un ambiente dal chiamante execveal nuovo processo.

Il kernel non esegue alcuna interpretazione nel percorso execve(dipende dalle funzioni wrapper come execvpeseguire la ricerca PATH) o in uno shebang (che reindirizza più o meno la execvechiamata internamente). Quindi devi inserire il percorso assoluto nello shebang¹. L' implementazione originale di shebang era solo poche righe di codice e da allora non è stata ampliata in modo significativo.

Nelle prime versioni di Unix, la shell ha fatto il lavoro di invocare se stessa quando ha notato che si stava invocando uno script. Shebang è stato aggiunto nel kernel per diversi motivi (riassumendo la logica di Dennis Ritchie :

  • Il chiamante non deve preoccuparsi se un programma da eseguire è uno script shell o un binario nativo.
  • Lo script stesso specifica quale interprete utilizzare, anziché il chiamante.
  • Il kernel usa il nome dello script nei log.

Shebang senza percorso richiederebbe sia di aumentare il kernel per accedere alle variabili di ambiente e di elaborare PATH, sia di far eseguire al kernel un programma di spazio utente che esegue la ricerca PATH. Il primo metodo richiede l'aggiunta di una quantità sproporzionata di complessità al kernel. Il secondo metodo è già possibile con uno #!/usr/bin/envshebang .

¹ Se si inserisce un percorso relativo, viene interpretato relativamente alla directory corrente del processo (non alla directory contenente lo script), che non è molto utile in un shebang.


2
No, il kernel non richiede un percorso assoluto execvené nello shebang sebbene abbia poco senso avere un percorso relativo in uno shebang.
Stéphane Chazelas,

3
Per chiunque sia curioso di sapere come "shebang reindirizza internamente la chiamata execve": In realtà fa parte di un meccanismo generico per eseguire interpreti su eseguibili che ne hanno bisogno. Gli eseguibili ELF collegati dinamicamente vengono "interpretati" da /lib64/ld-linux-x86-64.so.2(vedi lddoutput). Linux lo rende completamente generico: il binfmtsupporto (dalla 2.1.43) consente di registrare coppie di interpreti-path / magic-number-or-file-extension. Puoi far .exeinvocare PE32 winequando li esegui, invocare i file di classe Java e jar java, ecc. Ecc.
Peter Cordes,

#! / usr / bin / env -S [shebang] mi è stato richiesto di eseguire il nodo senza conoscerne il percorso (usando nvm - che lo colloca in una posizione diversa da quella che mi aspettavo inizialmente).
TamusJRoyce,

-S è disponibile solo dalle coreutils 8.30. Vedi gitlab.com/gnuwget/wget/commit/… .
Tim Ruehsen rockdaboot

19

C'è di più in corso di quanto sembri. #!le linee vengono interpretate dal kernel Unix o Linux, #!non è un aspetto delle shell. Ciò significa che PATHnon esiste davvero nel momento in cui il kernel decide cosa eseguire.

Il modo più comune per affrontare il non sapere quale eseguibile eseguire o chiamare perlin modo portatile o simile è usare #!/usr/bin/env perl. Viene eseguito il kernel /usr/bin/env, che eredita una PATHvariabile di ambiente. envreperti (in questo esempio) perlin PATHe utilizza il execve(2)chiamata di sistema per ottenere il kernel per eseguire il perlfile eseguibile.


4
$ strace sleep 1
execve("/usr/bin/sleep", ["sleep", "1"], [/* 99 vars */]) = 0

La conversione al percorso completo viene eseguita dalla shell (più generale: nello spazio utente). Il kernel si aspetta un nome file / percorso a cui può accedere direttamente.

Se vuoi che il sistema trovi il tuo eseguibile guardando attraverso la variabile PATH, puoi riscrivere il tuo shebang come #!/usr/bin/env EXEC.

Ma anche in questo caso non è il kernel che esegue la ricerca.


1
La conversione al percorso completo viene eseguita dalla shell Grazie, anche se ... l'esempio dovrebbe illustrarlo? A mio modo di vedere, la shell è in esecuzione strace(convertita ad un /usr/bin/stracecerto punto) con 2 argomenti.
Alois Mahdal,
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.