2013-07-07 11 views
30

を私はspawnは、Windows 7上のnpm install(続くrm -rf node_modulesを達成するために取得しようとしている。nは xの礼儀を指令します透明にインストールされたCygWin。すべてn xコマンドはコマンドラインで解決します。nodejsの卵を使用すると、「未知のオプション - 」引き起こし、「[エラー:スポーンENOENT]」エラー

私は当初execを使っていましたが、発生したstdout/stderr情報をキャッチしたかったので、spawnを使用してコードを書き換えました。しかし、それはすべてを破ります。

var spawn = require("child_process").spawn, 
    child = spawn("rm", ["-rf", "node_modules"]); 
child.stdout.on('data', function (data) { console.log(data.toString()); }); 
child.stderr.on('data', function (data) { console.log(data.toString()); }); 
child.on('error', function() { console.log(arguments); }); 

しかし、これを実行すると、次のエラーを生成します:

var spawn = require("child_process").spawn, 
    child = spawn("npm", ["install"]); 
child.stdout.on('data', function (data) { console.log(data.toString()); }); 
child.stderr.on('data', function (data) { console.log(data.toString()); }); 
child.on('error', function() { console.log(arguments); }); 
:書き換え

rm: unknown option -- , 

Try `rm --help' for more information. 

npmコマンドは、このになった書き換え

rmコマンドは、このになりました

しかし、これを実行すると、エラー:

{ 
    '0': { 
    [Error: spawn ENOENT] 
    code: 'ENOENT', 
    errno: 'ENOENT', 
    syscall: 'spawn' 
    } 
} 

がどのように私は卵が、それはすべての場所でエラーを投げずにexecを使用してうまく働いた同じコマンドを実行するのですか?そして、なぜこれはうまくいかないのですか? APIを読むとhttp://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_optionsは、これが正確にどのようにスポーンを使うべきかを示唆しているようです...

答えて

55

さまざまなことを試してみた結果、最終的には "npm"が実際にウィンドウに表示され、npmという名前のbashスクリプトと、npm.cmdというWindows固有のバッチスクリプトが判明しましたなぜそれが.cmdなのかわからない、それは.batでなければならないが、そこにある)。 Windowsのコマンドリゾルバはnpmと表示され、実行可能ファイルではないことに気付きます。npm.cmdを参照してください。そして、それが実行可能ファイルであることに気づき、代わりにそのファイルを使用します。これは、あなたが端末にいるときに役に立ちますが、spawn()はそのような解決を行いません。npmを渡すと、実行ファイルではないため失敗します。しかし、それをコマンドとしてnpm.cmdに渡すとうまくいきます。

は(また、それは実際に私が言うことができる任意の変更をせずに正しく動作するのでrmは、以前に失敗した理由がわからない。おそらく読み違えている問題、それはなかった、それは事実。の一部として)だから、

spawnにWindowsのENOENTと表示されている場合、トリガーしようとしているコマンドが普通のコマンドプロンプトで動作している場合は、呼び出しているコマンドが本当の実行可能ファイルかどうか、または.bat/.cmdファイル代わりにコマンドプロンプトが "有益に"実行されます。もしそうなら、それを産む。

編集

このポストはまだupvotesを取得しているため、コマンドを確保するための良い方法は、常に動作しますが、Windows用のwin32される、process.platformに基づいて、それをブートストラップすることです。

var npm = (process.platform === "win32" ? "npm.cmd" : "npm"), 
    child = spawn(npm, ["install", ...]); 
... 
+1

'.cmd'ファイルは[ほぼ同じものです](http://stackoverflow.com/questions/148968/windows-batch-files-bat-vs-cmd)ですが、それほどではありません。 – tadman

+1

'spawn'が失敗したウィンドウで実際に動作する' exec( "npm install ...") 'を使うことができました。 'exec'はライブstdout/stderrデータ(AFAIK)を与えませんが。 –

+2

いいえ私は持つことができませんでした。あなたが指摘しているように、execはstdoutとstderrの処理を持たず、ログなしでnpmをインストールするとかなり役に立たなくなります。 –

0

これはcygwin gotchaの何らかの種類かもしれないと思います。私はUbuntu 12.04を実行していて問題を再現しようとしましたが、うまく動作します。要するに、あなたが間違っていることは何も見ません。

それはオプション文句をされている場合は、多分そうのような複数のオプションにそれを分割:

child = spawn("rm", ["-r", "-f", "node_modules"]); 

雹メアリーのようなものだが、それは同様に私のUbuntu 12.04上で動作すること。 1つのファイルを削除して、同じことが起こっているかどうかを確認することもできます。

child = spawn("rm", ["/home/username/Desktop/TestFile"]); 

それでも失敗すると、あなたは何か狂ったことに取り組んでいることを知っています。

あなたも、ちょうどそのようなパラメータなしでコマンドを実行しようとすることができます:

child = spawn("ls"); 

それがまだ失敗した場合は、卵がすべてで動作するように取得する可能性はありません私の推測であることと感謝されます少なくとも幹部は働いている。

あなたの答えの領域はあまりありませんが、私が言ったように、間違っていることは何も見えません。

さらに、インストールするものを指定していないためにnpmコマンドがどのように動作するのかわかりませんが、それは違う方法で失敗します。同じコマンドを使用してください。 。 。私は、全体的なエラーではなく、stderr出力の多くを参照してください。

私はノードv0.8.21を実行しています。あなたはそれをノード-vで問い合わせることができます。別のバージョンを使用している場合は、0.8を与えるかもしれません。21 a try。

+0

は、それがさらに楽しくよりも判明しました。実際に何が起こったのかを説明する回答を追加しました。 –

+0

私はcygwinを実行しないので実行可能なものはわかりませんが、execまたはspawnはcygwinを最初に実行する必要があり、次にcygwinは 'rm'を実行します。 –

-1

プロセスに使用する完全なパス、のように:

var cmd = require('child_process').spawn("C:\\windows\\system32\\cmd.exe"); 
+1

は、実行可能ファイルの拡張子と場所をすでに知っている場合にのみ機能します。それらをハードコーディングすると、プロジェクトが他の人のコンピュータ上で作業するのを瞬時に止め、クロスプラットフォームで作業することはできません。 –