LoginSignup
18
15

More than 5 years have passed since last update.

npm-cli.jsがShellScriptとしてもJavaScriptとしてもWSHとしても実行できてきもちわるい

Last updated at Posted at 2013-12-10

共用サーバに置いていた/usr/local/nodejs/bin/npmが消失するという奇怪な事件が発生した。この問題の原因はわからないが、とりあえず適当に復旧させようとおもって、npm周りを見ていた。npmというコマンドの実体はnpm-cli.jsへのシンボリックリンクになっている。

で、中身を見ていると次のようになっていた。

npm-cli.js
#!/bin/sh
// 2>/dev/null; exec "`dirname "$0"`/node" "$0" "$@"
;(function () { // wrapper in case we're in module_context mode

// windows: running "npm blah" in this folder will invoke WSH, not node.
if (typeof WScript !== "undefined") {
  WScript.echo("npm does not work when run\n"
              +"with the Windows Scripting Host\n\n"
              +"'cd' to a different directory,\n"
              +"or type 'npm.cmd <args>',\n"
              +"or type 'node npm <args>'.")
  WScript.quit(1)
  return
}

process.title = "npm"

var log = require("npmlog")
log.pause() // will be unpaused when config is loaded.
log.info("it worked if it ends with", "ok")
...

ShellScriptとして実行できる

shebangを見るとどう見ても/bin/shである。それなのに、JavaScriptのコードが続いてるではないか。よくよく見ていると2行目が奇妙なことになっていることに気がつく。

npm-cli.js
#!/bin/sh
// 2>/dev/null; exec "`dirname "$0"`/node" "$0" "$@"

//で始まってるので、JavaScriptではコメントとして処理される(shebangはどう扱われるんだろう?)。しかし、ShellScriptは//でコメントアウトできないため、コマンドとして実行されてエラーになる。エラーになるけど、出力は/dev/nullに送られて、その後のコマンドが実行される。結果として、自分自身のファイル名がnodeコマンドの引数に渡されて実行される。

WSHとしても実行できる

続きをみると次のようになっている。

npm-cli.js
// windows: running "npm blah" in this folder will invoke WSH, not node.
if (typeof WScript !== "undefined") {
  WScript.echo("npm does not work when run\n"
              +"with the Windows Scripting Host\n\n"
              +"'cd' to a different directory,\n"
              +"or type 'npm.cmd <args>',\n"
              +"or type 'node npm <args>'.")
  WScript.quit(1)
  return
}

WScriptというのはWindowsのWSHでしか定義されていないオブジェクトらしく、WSHとして実行されるとエラーメッセージを表示するようだ。

まとめ

いろんな環境に対応しててすごい。

18
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
15