Criando um shebang apontando portavelmente para um interpretador na pasta de um script

5

Eu tenho um arquivo JS ( file.js ) que eu quero ter executado como um script de shell de linha de comando através de nodejs (iojs atualmente); Estou usando o MINGW Git Bash no Windows.

A maneira padrão de fazer isso é colocar a seguinte shebang no arquivo JS:

#!/usr/bin/env node

No entanto, quero passar um sinalizador de linha cmd para o nó para ativar os recursos de harmonia do V8, ou seja, eu quero um equivalente de

node --harmony_arrow_functions file.js

quando executado da mesma maneira que

./file.js

sem a necessidade de passar a bandeira manualmente.

Usando

#!/usr/bin/env node --harmony_arrow_functions

não funciona.

Depois de considerar o link e link criei a seguinte solução:

$ ls
file.js nodeharmony.sh

$ cat nodeharmony.sh
#!/bin/sh
exec node --harmony_arrow_functions "$@"

$ cat file.js
#!/bin/sh nodeharmony.sh               # or ./nodeharmony.sh, doesn't matter
console.log("Hello world")

$ ./file.js    # this works fine
Hello world

Mas o problema é que quando eu o executo de outra pasta, o shell tenta encontrar nodeharmony.sh no diretório de trabalho atual, não o diretório de file.js :

$ cd ..
$ ./subfolder/file.js
/bin/sh: ./nodeharmony.sh: No such file or directory

Existe uma maneira de criar um shebang portátil em file.js , de modo que eu possa executar file.js de qualquer pasta, sem precisar ter meu intérprete personalizado ( nodeharmony.sh ) disponível no PATH ?

Editar:

O ficheiro JS tem de permanecer um ficheiro JavaScript válido, pelo que não pode ter mais de uma% inicial #! line , ou seja, quando altero file.js para

#!/bin/sh
exec $(dirname $0)/nodeharmony.sh "$0"
console.log("Hello world")

em seguida, o shell passa corretamente o nome e o argumento do dir, mas ele falha no lado do Node, pois o arquivo não é um código JS válido:

$ ./subfolder/file.js
d:\CODE\subfolder\file.js:2
exec $(dirname $0)/nodeharmony.sh $0
     ^
SyntaxError: Unexpected identifier
    at exports.runInThisContext (vm.js:54:16)
    ...

Editar 2:

Eu também gostaria de manter a possibilidade de executar o meu script através de

./file.js

bem como

node --harmony_arrow_functions ./file.js

Assim, o corte sugerido para sed do conteúdo do arquivo, excluir cabeçalho e canalizá-lo para o nó no shebang não é bom neste contexto, já que a execução posterior será impossível.

    
por jakub.g 01.02.2015 / 12:32

2 respostas

1

Você pode produzir um script de nó que também é um script de shell válido para fazer isso:

#!/bin/sh
//usr/bin/env node --harmony_arrow_functions "$0" "$@"; exit $?

console.log("Hello world")

Salvar isso como file.js produz um script que pode ser executado em qualquer lugar. Depende de // ser equivalente a / ; Eu não testei isso no Windows ...

    
por 01.02.2015 / 19:00
1

EDIT: (A resposta original ainda responde à questão declarada, mas de fato faz com que file.js não seja um arquivo JS válido). Para permitir o comportamento desejado, segue um shebang + 1st-line-combination que alimentará o arquivo.js através de node pulando as duas primeiras linhas, alimentando-o apenas com o código JS:

#!/bin/sh
sed '1,2d' $0 |node --harmony_arrow_functions; exit $?
/* Your JS code begins here */

--- Abaixo da resposta original ---

Se você pode contar com certeza que seu interpretador estará no mesmo diretório do arquivo interpretado (que é a questão declarada), você pode usar $(dirname $0) para obter seu caminho.

Exemplo:

#!/bin/sh
exec $(dirname $0)/nodeharmony.sh "$0" "$@"

Neste caso, ao executar

$ cd ..
$ ./subfolder/file.js

O $(dirname $0) será resolvido para ./subfolder , portanto, o exec usará ./subfolder/nodeharmony.sh como o interpretador.

    
por 01.02.2015 / 12:48