Desde la página del lenguaje de comandos de Shell de la especificación POSIX:
Si la primera línea de un archivo de comandos de shell comienza con los caracteres "#!", Los resultados no se especifican.
¿Por qué el comportamiento de #!
no especificado por POSIX? Me resulta desconcertante que algo tan portátil y ampliamente utilizado tenga un comportamiento no especificado.
exec()
función. Por lo tanto, verificar contra múltiples proyectiles realmente no le dice qué tan portátil es.Respuestas:
Pienso principalmente porque:
El comportamiento varía mucho entre la implementación. Ver https://www.in-ulm.de/~mascheck/various/shebang/ para todos los detalles.
Sin embargo, ahora podría especificar un subconjunto mínimo de la mayoría de las implementaciones tipo Unix: como
#! *[^ ]+( +[^ ]+)?\n
(con solo caracteres del conjunto de caracteres de nombre de archivo portátil en esas una o dos palabras) donde la primera palabra es una ruta absoluta a un ejecutable nativo, la cosa no es demasiado largo y comportamiento no especificado si el ejecutable es setuid / setgid, y la implementación definió si la ruta del intérprete o la ruta del script se pasaargv[0]
al intérprete.POSIX no especifica la ruta de los ejecutables de todos modos. Varios sistemas tienen utilidades pre-POSIX en
/bin
//usr/bin
y tienen las utilidades POSIX en otro lugar (como en Solaris 10 donde/bin/sh
hay un shell Bourne y el POSIX está en/usr/xpg4/bin
; Solaris 11 lo reemplazó con ksh93 que es más compatible con POSIX, pero la mayoría de los otros las herramientas/bin
todavía son antiguas y no POSIX). Algunos sistemas no son POSIX pero tienen un modo / emulación POSIX. Todo lo que requiere POSIX es que haya un entorno documentado en el que un sistema se comporte POSIXly.Ver Windows + Cygwin por ejemplo. En realidad, con Windows + Cygwin, el she-bang se honra cuando una aplicación cygwin invoca un script, pero no una aplicación nativa de Windows.
Entonces, incluso si POSIX especificó el mecanismo shebang, no podría usarse para escribir scripts POSIX
sh
/sed
/awk
... (también tenga en cuenta que el mecanismo shebang no puede usarse para escribir confiablesed
/awk
scripts ya que no permite pasar un fin de opción marcador).Ahora, el hecho de que no esté especificado no significa que no pueda usarlo (bueno, dice que no debe comenzar la primera línea con
#!
si esperas que sea solo un comentario regular y no una explosión), pero POSIX no le garantiza si lo hace.En mi experiencia, el uso de shebangs le brinda más garantía de portabilidad que el uso de la forma en que POSIX escribe scripts de shell: omita she-bang, escriba el script en
sh
sintaxis POSIX y espere que cualquier cosa que invoque el script invoque un POSIX compatiblesh
con él, que es bien si sabe que la herramienta correcta invocará el script en el entorno correcto, pero no de otra manera.Puede que tenga que hacer cosas como:
Si quieres ser portátil a Windows + Cygwin, es posible que tenga el nombre de su archivo con una
.bat
o.ps1
extensión y utilizar algún truco similar paracmd.exe
opowershell.exe
para invocar el cygwinsh
en el mismo archivo.fuente
sh
, no necesitaría una línea hashbang, ya que POSIX la ejecutaríash
.execlp
oexecvp
no, ¿verdad? Siexecve
tuviera que usar , ¿resultaría en ENOEXEC?No estás mirando lo suficientemente profundo.
En la década de 1980, este mecanismo fue no estandarizado de facto. Aunque Dennis Ritchie lo había implementado, esa implementación no había llegado al público en el lado AT&T del universo. Efectivamente, solo estaba disponible públicamente y se conocía en BSD; con scripts de shell ejecutables no disponibles en AT&T Unix. Por lo tanto, no era razonable estandarizarlo. El estado de cosas está ejemplificado por este doco contemporáneo, uno de muchos de ellos:
- Stephen Frede (1988). "Programación en el sistema X Release Y". Boletín del grupo de usuarios de Australia Unix Systems . Volumen 9. Número 4. p. 111)Un punto importante aquí es que está mirando shells, mientras que la existencia de scripts de shell ejecutables es realmente un asunto de las
exec…()
funciones. Lo que hacen los shells incluye los precursores del mecanismo de script ejecutable, que todavía se encuentra en algunos shells aún hoy (y también hoy en día es obligatorio para elexec…p()
subconjunto de funciones), y es algo engañoso. Lo que el estándar debe abordar a este respecto es cómo funcionaexec…()
un script interpretado, y en el momento en que POSIX se creó originalmente , simplemente no funcionó en primer lugar en una parte importante del espectro de los sistemas operativos de destino .Una pregunta subordinada es por qué esto no se ha estandarizado desde entonces, especialmente porque el mecanismo del número mágico para los intérpretes de guiones había llegado al público en el lado AT&T del universo y se había documentado
-exec…()
en la Definición de interfaz del Sistema 5 , a fines de la década de 1990 :exec
. Definición V System Interface . Volumen 1. 1991.Desafortunadamente, el comportamiento sigue siendo hoy casi tan divergente como lo era en la década de 1980 y no hay un comportamiento verdaderamente común para estandarizar. Algunos Unices (famosos HP-UX y FreeBSD, por ejemplo) no admiten scripts como intérpretes para scripts. Si la primera línea es uno, dos o muchos elementos separados por espacios en blanco varía entre MacOS (y las versiones de FreeBSD anteriores a 2005) y otros. La longitud máxima de ruta admitida varía.
␀
y los caracteres que se encuentran fuera del juego de caracteres de nombre de archivo portátil POSIX son complicados, al igual que los espacios en blanco iniciales y finales. Lo que terminan siendo el 0º, 1º y 2º argumento también es complicado, con una variación significativa entre los sistemas. Algunos actualmente son compatibles con POSIX pero no-Los sistemas Unix todavía no admiten ningún mecanismo de este tipo, y su mandato los convertiría en no más compatibles con POSIX.Otras lecturas
script
. Manual de información diversa de NetBSD . 2005-05-06.fuente
Como se señaló en algunas de las otras respuestas, las implementaciones varían. Esto hace que sea difícil estandarizar y preservar la compatibilidad con versiones anteriores de los scripts existentes. Esto es cierto incluso para los sistemas POSIX modernos. Por ejemplo, Linux no tokeniza completamente la línea shebang por espacios. macOS no permite que el intérprete de guiones sea otro guión.
Ver también http://en.wikipedia.org/wiki/Shebang_(Unix)#Portability
fuente