Question

I'm currently working on pm2, a process manager for NodeJS.

As it's targeted at Javascript, a new standard is coming, ES6. To enable it on NodeJS I have to add the option --harmony.

Now for the bash part, I have to let the user pass this option to the interpreter that executes the file. By crawling the web (and found on Stackoverflow) I found this :

#!/bin/sh

':' //; exec "`command -v nodejs || command -v node`" $PM2_NODE_OPTIONS "$0" "$@"

bin line

Looks like a nice hack but is it portable enough ? On CentOS, FreeBSD...

It's kind of critical so I want to be sure.

Thank you

Était-ce utile?

La solution

Let's break down the line of interest.

: is a do nothing in shells.

; is a command separator.

exec will replace the current process with the process of the command that it is executing.

Notice that in the exec command it passes "$0" and "$@" as parameter to the command?

This will allow the new process to read the script denoted by $0 and use it as a script input and reads the original parameters as well $@

The new process will read the input script from the beginning and ignore the comments like #!/bin/sh. and will also ignore :.

Here's the trick. Most interpreters, including perl, uses syntax that are ignored by shell or vice-versa so that on re-reading the input file, the interpreter will not exec itself again.

In this case, the new process ignored the whole line from :. The reason why the rest of the line is ignored? On some c like interpreters, // is a comment.

I forgot to answer your question. Yes it seems portable. There may be corner cases but I can't think of any right now.

Autres conseils

To enable it on NodeJS I have to add the option --harmony.

Not necessarily. You can use normal "#!/usr/bin/env node" shebang, but set a harmony flags in runtime using setflags module.

I'm not sure it's better solution, but it's worth mentioning.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top