Saltar al contenido

¿Qué hace exactamente “/ usr / bin / env node” al comienzo de los archivos de nodo?

Después de de una prolongada compilación de datos dimos con la solución esta escollo que suelen tener muchos de nuestros usuarios. Te dejamos la respuesta y nuestro deseo es servirte de mucha apoyo.

Solución:

#!/usr/bin/env node es una instancia de una línea shebang: los primera línea en un archivo ejecutable de texto sin formato en Plataformas tipo Unix que le dice al sistema a qué intérprete pasar ese archivo para su ejecución, a través de la línea de comando siguiendo la magia #! prefix (llamado el asunto).

Nota: Ventanas lo hace no apoyar líneas shebang, por lo que son efectivamente ignorado allí; en Windows es únicamente un archivo dado extensión de nombre de archivo que determina qué ejecutable lo interpretará. Sin embargo, todavía los necesita en el contexto de npm.[1]

El seguimiento, discusión general de las líneas shebang está limitado a plataformas similares a Unix:

En la siguiente discusión, asumiré que el archivo que contiene el código fuente para ser ejecutado por Node.js simplemente se llama file.

  • usted NECESITO esta línea, si desea invocar un archivo fuente de Node.js directamente, como un ejecutable por derecho propio: esto supone que el archivo se ha marcado como ejecutable con un comando como chmod +x ./file, que luego le permite invocar el archivo con, por ejemplo, ./file, o, si se encuentra en uno de los directorios enumerados en el $PATH variable, simplemente como file.

    • Específicamente, necesitas una línea shebang para crear CLI basado en archivos fuente de Node.js como parte de un npm paquete, con las CLI que instalará npm basado en el valor de la "bin" key en un paquete package.json expediente; también vea esta respuesta para saber cómo funciona eso con globalmente paquetes instalados. Nota [1] muestra cómo se maneja esto en Windows.
  • usted No necesitas esta línea para invocar un archivo explícitamente a través del node intérprete, p. ej., node ./file


Información de antecedentes opcional:

#!/usr/bin/env es una forma de portátil especificando un intérprete: en pocas palabras, dice: ejecutar donde (primero) lo encuentre entre los directorios listados en el $PATH variable (e implícitamente pasarle la ruta al archivo en cuestión).

Esto explica el hecho de que un intérprete determinado puede instalarse en diferentes ubicaciones a través de plataformas, lo que definitivamente es el caso de node, el binario de Node.js.

Por el contrario, la ubicación del env Se puede confiar en que la utilidad en s misma est en el mismo ubicación a través de plataformas, a saber /usr/bin/env – y especificando el lleno la ruta a un ejecutable es requerido en una línea de shebang.

Tenga en cuenta que la utilidad POSIX env está siendo reutilizado aquí para localizar por nombre de archivo y ejecutar un ejecutable en el $PATH.
los true propósito de env es administrar el entorno para un comando; consulte envPOSIX y la útil respuesta de Keith Thompson.


También vale la pena señalar que Node.js está creando una sintaxis excepción para las líneas shebang, dado que no son un código JavaScript válido (# no es un carácter de comentario en JavaScript, a diferencia de los shells similares a POSIX y otros intérpretes).


[1] En aras de la coherencia multiplataforma, npm crea envoltura*.cmd archivos (archivos por lotes) en Windows al instalar ejecutables especificados en un paquete package.json archivo (a través del "bin" propiedad). Básicamente, estos archivos por lotes de contenedor imitar Funcionalidad shebang de Unix: ellos invocar el archivo de destino explícitamente con el ejecutable especificado en la línea shebang – por lo tanto, sus scripts deben incluir una línea shebang incluso si solo tiene la intención de ejecutarlos en Windows – vea esta respuesta mía para más detalles.
Ya que *.cmd los archivos se pueden invocar sin la .cmd extensión, esto lo convierte en una experiencia multiplataforma perfecta: tanto en Windows como en Unix puede invocar de manera efectiva un npm-instalado CLI por su nombre original, sin extensión.

Los scripts que deben ser ejecutados por un intérprete normalmente tienen una línea shebang en la parte superior para indicarle al sistema operativo cómo ejecutarlos.

Si tiene un script llamado foo cuya primera línea es #!/bin/sh, el sistema leerá esa primera línea y ejecutará el equivalente de /bin/sh foo. Debido a esto, la mayoría de los intérpretes están configurados para aceptar el nombre de un archivo de secuencia de comandos como argumento de línea de comandos.

El nombre del intérprete que sigue al #! tiene que ser un camino completo; el sistema operativo no buscará su $PATH para encontrar el intérprete.

Si tiene un script para ser ejecutado por node, la forma obvia de escribir la primera línea es:

#!/usr/bin/node

pero eso no funciona si el node el comando no está instalado en /usr/bin.

Una solución alternativa común es utilizar el env comando (que no era De Verdad destinado a este fin):

#!/usr/bin/env node

Si su secuencia de comandos se llama foo, el sistema operativo hará el equivalente a

/usr/bin/env node foo

los env comando ejecuta otro comando cuyo nombre se da en su línea de comando, pasando los siguientes argumentos a ese comando. La razón por la que se usa aquí es que env buscará $PATH para el comando. Así que si node está instalado en /usr/local/bin/node, y tu tienes /usr/local/bin en tus $PATH, los env el comando invocará /usr/local/bin/node foo.

El objetivo principal de la env comando es ejecutar otro comando con un entorno modificado, agregando o eliminando variables de entorno especificadas antes de ejecutar el comando. Pero sin argumentos adicionales, simplemente ejecuta el comando con un entorno sin cambios, que es todo lo que necesita en este caso.

Hay algunos inconvenientes en este enfoque. La mayoría de los sistemas modernos tipo Unix tienen /usr/bin/env, pero trabajé en sistemas más antiguos donde el env El comando se instaló en un directorio diferente. Puede haber limitaciones en los argumentos adicionales que puede pasar utilizando este mecanismo. Si el usuario no tener el directorio que contiene el node comando en $PATH, o tiene algún comando diferente llamado node, entonces podría invocar el comando incorrecto o no funcionar en absoluto.

Otros enfoques son:

  • Utilizar una #! línea que especifica la ruta completa a la node comando en sí mismo, actualizando el script según sea necesario para diferentes sistemas; o
  • Invocar el node comando con su script como argumento.

Consulte también esta pregunta (y mi respuesta) para obtener más información sobre el #!/usr/bin/env truco.

Por cierto, en mi sistema (Linux Mint 17.2), está instalado como /usr/bin/nodejs. Según mis notas, cambió de /usr/bin/node para /usr/bin/nodejs entre Ubuntu 12.04 y 12.10. los #!/usr/bin/env truco no ayudará con eso (a menos que configure un enlace simbólico o algo similar).

ACTUALIZACIÓN: Un comentario de mtraceur dice (reformateado):

Una solución para el problema de nodejs vs node es iniciar el archivo con las siguientes seis líneas:

#!/bin/sh -
':' /*-
test1=$(nodejs --version 2>&1) && exec nodejs "$0" "[email protected]"
test2=$(node --version 2>&1) && exec node "$0" "[email protected]"
exec printf '%sn' "$test1" "$test2" 1>&2
*/

Esto primero intentará nodejs y luego intenta nodey solo imprima los mensajes de error si no se encuentran ninguno de los dos. Una explicación está fuera del alcance de estos comentarios, solo la dejo aquí en caso de que ayude a alguien a lidiar con el problema, ya que esta respuesta planteó el problema.

No he usado NodeJS últimamente. Mi esperanza es que el nodejs vs. node El problema se ha resuelto en los años desde que publiqué esta respuesta por primera vez. En Ubuntu 18.04, el nodejs instalación del paquete /usr/bin/nodejs como enlace simbólico a /usr/bin/node. En algunos sistemas operativos anteriores (Ubuntu o Linux Mint, no estoy seguro de cuál), había un nodejs-legacy paquete que proporcionó node como enlace simbólico a nodejs. No hay garantía de que tenga todos los detalles correctos.

Sección de Reseñas y Valoraciones

Acuérdate de que tienes autorización de interpretar tu experiencia si diste con la contestación.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *