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 comofile
.- 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 paquetepackage.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.
- 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á
-
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 env
POSIX 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 lanode
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 intentanode
y 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.