¿Qué tipo de camino en shebang es más preferible?

20

En los scripts, la primera línea debe especificar la ruta al intérprete.
Pero en diferentes servidores Linux, Unix o BSD, esta ruta podría ser diferente.

¿Qué es más preferible?

#!/usr/bin/env bash 

o

#!/bin/bash 
Roman Ivanov
fuente

Respuestas:

22

Si desea utilizar la versión instalada de sistema de un intérprete determinado que está instalado en una ubicación estándar, utilice la ruta directa. Si desea usar cualquier versión del intérprete que aparezca primero en el usuario $PATH, use#!/usr/bin/env ... .

El envcomando invoca un comando específico, lo que le permite establecer o deshabilitar variables de entorno:

env FOO=BAR do-something
env DISPLAY=:0.0 xterm -ls &

Si no especifica ninguna variable de entorno u otras opciones, solo invocará el comando con nombre. (Usarlo de esta manera es posiblemente un truco).

El propósito de escribir el shebang como

#!/usr/bin/env interp

es invocar lo que interpaparece primero $PATH.

Esto significa que usted no tiene que saber, al escribir el guión, exactamente donde interpes (por ejemplo, si se pudiera estar en cualquiera /bin, /usr/bino /usr/local/bin). Por supuesto que tienes que saber que enves/usr/bin/env , pero parece ser razonablemente universal.

La ventaja es que invoca cualquier versión del intérprete que aparezca primero en el usuario $PATH. La desventaja es que invoca cualquier versión del intérprete que aparece primero en el usuario $PATH.

Por ejemplo, supongamos que he instalado una compilación personal perlen mi directorio de inicio, como $HOME/bin/perl, y que tengo $HOME/binal frente de mi $PATH. Si ejecuto un script cuyo shebang es

#!/usr/bin/env perl

entonces se ejecutará con mi propio instalado perl ejecutable , lo que podría no ser algo bueno. El autor del guion probablemente no lo haya probado con el perl de filo que construí desde la fuente hace un mes.

Para algo como Perl o Bash que probablemente se instale en una ubicación coherente en la mayoría de los sistemas ( /usr/bin/perly /bin/bash, respectivamente), usaría la ruta directa al comando. Para algo más oscuro que podría instalarse de manera diferente en diferentes sistemas, usaría el /usr/bin/envtruco o escribiría un instalador que ajuste la línea shebang a medida que se instala el script. (Solía ​​tener que hacer eso para mis scripts de Perl).

ACTUALIZACIÓN: He entrado un poco más en detalle en esta respuesta a esta pregunta en el sitio de Unix y Linux .

Keith Thompson
fuente
Acabo de empezar a buscar en Ruby, y descubrí que la convención en Ruby es comenzar con [code] #! / Usr / bin / env ruby ​​[/ code] en aras de la portabilidad. Algunos señalaron que esto dificulta el suministro de argumentos de línea de comandos al intérprete de ruby, como '-w', que también sería un problema para Perl.
bgvaughan
@bgvaughan Para Perl, hoy en día es tradicional usarlo #!/usr/bin/perly luego usarlo use strict; use warnings;en el cuerpo del script, en lugar de hacerlo #!/usr/bin/perl -w. Pero -Ttiene que estar en el shebang.
Keith Thompson
entonces, ¿por qué no usar #! perl si solo queremos el primero en el camino?
Wheredidthatnamecomerom
@wheredidthatnamecomefrom: Porque eso no funciona. El tratamiento de la #!línea no sirve $PATH. Debe especificar la ruta del intérprete. (Me acabo de dar cuenta de que, al menos en mi sistema, puede ser una ruta relativa, pero rara vez es útil.)
Keith Thompson
6

La mejor práctica es esta:

#!/usr/bin/env bash 
#!/usr/bin/env sh
#!/usr/bin/env python

Y así...

Cuando Ubuntu comenzó a usar dash, algunos scripts se rompieron. Hubo una discusión al respecto. La mayoría de los guiones fueron escritos, lo #!/bin/shque era un enlace a / bin / bash. El consenso es este: el guionista es responsable de especificar el intérprete. Por lo tanto, si su script siempre debe invocarse con BASH, especifíquelo desde el entorno. Esto le ahorra tener que adivinar la ruta, que es diferente en varios sistemas Unix / Linux. Además, funcionará si mañana / bin / sh se convierte en un enlace a otro shell como / bin / wthsh o alguna otra falta.


fuente
La solución alternativa obvia para el problema del guión era escribir #!/bin/bash. Estoy de acuerdo en que el guionista es responsable de especificar el intérprete, pero todo lo que significa es que si necesita bash, digamos bash not sh
Martin Bonner apoya a Monica el
1

FYI, es un shee-bang #!, necesitas el #. Utiliza esta línea para identificar con qué intérprete ejecutar el script.

Por defecto, Ubuntu enlaza /bin/shal tablero

Dependiendo de cuánto le gustaría saber sobre el tablero y por qué se usa el tablero para el sistema o las cubiertas de demonio, consulte:

cyberciti.biz dash

Ubuntu man man page

Bash es el shell predeterminado utilizado por la mayoría de los usuarios de Linux, y tiene diferentes características que el guión. Un script escrito para bash puede o no ejecutarse correctamente si se ejecuta con guión, cuanto más complejo sea el script, menos probable será que se ejecute.

El script escrito para perl, python, etc. no se ejecutará en absoluto con /bin/sho /bin/bash.

Entonces, cuando escribe un guión, identifica qué intérprete se debe usar con el shee-bang

La selección de qué usar es hecha por el autor del guión, y uno no es mejor que otro, todos tienen varias características, ventajas y desventajas.

Pantera
fuente