Hashbang apropiado para scripts de Node.js

95

Estoy tratando de crear un script para node.js que funcione en múltiples entornos. Particularmente para mí, estoy cambiando entre OS X y Ubuntu. En el primero, Node se instala como node, pero en el segundo lo es nodejs. En la parte superior de mi guión, puedo tener:

#!/usr/bin/env node

o

#!/usr/bin/env nodejs

Prefiero que el script se ejecute como un ejecutable para cualquier entorno siempre que el nodo esté instalado en lugar de que uno u otro tenga que especificar el comando ( ./script-name.jsvs. node script-name.js).

¿Hay alguna forma de especificar un hashbang de respaldo o uno que sea compatible en cualquier caso para node.js?

Pastillas de explosión
fuente
podría crear un script de shell contenedor para llamar a su script, que intenta averiguar dónde vive el nodo y cómo se llama.
Doon
4
Muchas sugerencias en esta respuesta en el sitio de Unix: unix.stackexchange.com/questions/65235/…
sargant
Tengo un script nodejs que he cambiado desde #!/usr/bin/nodeque #!/usr/bin/nodejscuando he actualizado desde Ubuntu 12.04 a 12.10. Y se invoca desde un contenedor que comprueba ambos. Para una discusión sobre el #!/usr/bin/envtruco, vea esta pregunta y mi respuesta .
Keith Thompson
1
Hay una propuesta de TC39 en la Etapa 3 llamada "Gramática de Hashbang" que tiene como objetivo estandarizar los hashbangs usados: github.com/tc39/proposal-hashbang
M. Twarog

Respuestas:

151

Si su script está diseñado para que lo utilicen desarrolladores de Node, debe usar

#!/usr/bin/env node

y no se moleste en probar la compatibilidad con personas que solo tienen Node instalado como nodejs.

Razón fundamental:

  • Es lo que hacen los niños geniales, y si no lo haces tú también, no eres genial. Grandes proyectos de nodos como jshint , el karma , glorieta , e incluso la NGP utilizan simplemente #!/usr/bin/env nodecomo el tinglado por sus secuencias de comandos ejecutables.
  • Debido a que los chicos geniales lo están haciendo, cualquiera que trabaje con Node en Ubuntu ha configurado /usr/bin/nodeun enlace simbólico a nodejs. Hay instrucciones muy consultadas sobre cómo hacer esto aquí en Stack Overflow y en toda la web. Incluso estaba el nodejs-legacypaquete cuyo único propósito era crear este enlace simbólico para usted. Las personas que usan Node saben cómo solucionar este problema en Ubuntu, y deben hacerlo si quieren usar prácticamente cualquier software escrito en Node.
  • El problema ni siquiera parece existir más en Ubuntu 14.04; Acabo de purgar Node y ejecuté un apt-get install nodejsy se creó /usr/bin/nodecomo un enlace simbólico a /etc/alternatives/node. Sospecho que las personas afectadas por este problema son una minoría cada vez menor.

Incluso si está apuntando a personas analfabetas de Node, es posible que aún desee usar #!/usr/bin/env node, quizás agregando la posible necesidad de creación manual de enlaces simbólicos o instalación del nodejs-legacypaquete a su documentación de instalación si lo considera necesario. Tenga en cuenta que si alguien con nodejspero no nodedisponible intenta ejecutar su programa con el shebang anterior, verá:

/ usr / bin / env: node: No existe tal archivo o directorio

y buscar en Google que les dará la solución en el primer resultado y muchas veces en la primera página.

Si realmente y desesperadamente desea asegurarse de que el usuario pueda ejecutar su software en un sistema donde nodejsestá disponible pero nodeno lo está (o dónde nodeestá realmente el programa Nodo de radio de paquetes amateur ), entonces puede usar este "shebang de dos líneas" tomado de Unix y Linux Stack Exchange :

#!/bin/sh
':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"

console.log('Hello world!');

pero, ¿realmente necesitas hacer esto cuando casi nadie más en el mundo Node lo hace?

Mark Amery
fuente
2
Si nodejsse prefiere la compatibilidad con el ejecutable, es posible que le resulte un poco más bonito usar un shebang con #!/bin/shy //bin/false || exec "$(command -v nodejs || command -v node)" "$0".
lennartcl
2
Tenga en cuenta que no puede pasar argumentos al nodo en Linux , por ejemplo --experimental-modules, si usa esta envlínea shebang. Hay trucos por ahí, pero son feos .
Dan Dascalescu