[解決済み] node.js シェルコマンドの実行
質問
LinuxやWindowsのシェルコマンドを実行し、node.jsの中で出力をキャプチャする方法について、まだ細かい点を把握しようとしています。
//pseudocode
output = run_command(cmd, args)
重要な部分は
output
がグローバルにスコープされた変数(またはオブジェクト)に対して利用可能でなければならないことです。 以下の関数を試してみましたが、なぜか
undefined
がコンソールに出力されてしまいます...。
function run_cmd(cmd, args, cb) {
var spawn = require('child_process').spawn
var child = spawn(cmd, args);
var me = this;
child.stdout.on('data', function(me, data) {
cb(me, data);
});
}
foo = new run_cmd('dir', ['/B'], function (me, data){me.stdout=data;});
console.log(foo.stdout); // yields "undefined" <------
上記のコードがどこで壊れているのか理解するのに苦労しています...そのモデルの非常に単純なプロトタイプは動作します...
function try_this(cmd, cb) {
var me = this;
cb(me, cmd)
}
bar = new try_this('guacamole', function (me, cmd){me.output=cmd;})
console.log(bar.output); // yields "guacamole" <----
どなたか、なぜ
try_this()
が機能しているのか、そして
run_cmd()
は動作しないのですか? 参考までに、私は
child_process.spawn
というのは
child_process.exec
には200KBのバッファ制限があるためです。
最終的な解決
James White氏の回答を受け入れていますが、これは私のために動作した正確なコードです...。
function cmd_exec(cmd, args, cb_stdout, cb_end) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args),
me = this;
me.exit = 0; // Send a cb to set 1 when cmd exits
me.stdout = "";
child.stdout.on('data', function (data) { cb_stdout(me, data) });
child.stdout.on('end', function () { cb_end(me) });
}
foo = new cmd_exec('netstat', ['-rn'],
function (me, data) {me.stdout += data.toString();},
function (me) {me.exit = 1;}
);
function log_console() {
console.log(foo.stdout);
}
setTimeout(
// wait 0.25 seconds and print the output
log_console,
250);
どのように解決するのですか?
ここでは、修正しなければならない3つの問題があります。
まず
は、stdoutを非同期で使用しながら、同期的な動作を期待していることです。あなたの
run_cmd
関数のすべての呼び出しは非同期なので、stdout からデータの一部、全部、または全部が読み込まれたかどうかに関係なく、子プロセスを生成してすぐに返します。そのため
console.log(foo.stdout);
を実行すると、その時点で foo.stdout に格納されているものは何でも得られますが、 子プロセスがまだ実行中かもしれないので、それが何であるかの保証はありません。
2 番目の は、stdout が 読みやすいストリーム であるため、1) データイベントを複数回呼び出すことができる、2) コールバックは文字列ではなくバッファを与えられる、です。改善するのは簡単で、単に
foo = new run_cmd(
'netstat.exe', ['-an'], function (me, data){me.stdout=data;}
);
に
foo = new run_cmd(
'netstat.exe', ['-an'], function (me, buffer){me.stdout+=buffer.toString();}
);
で、バッファを文字列に変換し、その文字列をstdout変数に追加しています。
第三の は、'end'イベントを取得したときにのみ、すべての出力を受け取ったことを知ることができるということです。これは、別のリスナーとコールバックが必要であることを意味します。
function run_cmd(cmd, args, cb, end) {
// ...
child.stdout.on('end', end);
}
で、最終的にはこうなります。
function run_cmd(cmd, args, cb, end) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args),
me = this;
child.stdout.on('data', function (buffer) { cb(me, buffer) });
child.stdout.on('end', end);
}
// Run C:\Windows\System32\netstat.exe -an
var foo = new run_cmd(
'netstat.exe', ['-an'],
function (me, buffer) { me.stdout += buffer.toString() },
function () { console.log(foo.stdout) }
);
関連
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] シェルで、「2>&1」はどういう意味ですか?
-
[解決済み] Node.jsのプログラムにコマンドライン引数を渡すにはどうしたらいいですか?
-
[解決済み] Node.jsを使うタイミングをどう判断するか?
-
[解決済み] Node.jsで終了する方法
-
[解決済み] Node.jsでファイルを書き込む
-
[解決済み] Bashシェルスクリプトの入力引数の存在確認
-
[解決済み] Node.jsアプリケーションをデバッグするにはどうすればよいですか?
-
[解決済み] シェルコマンドの実行と出力のキャプチャ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】child_process.execSyncを使用してもコンソールに出力され続ける
-
[解決済み] node.jsでシェルコマンドを実行し、その出力を取得する
-
[解決済み] Angular 2 パスが存在しない場合に404や他のパスにリダイレクトする方法 [重複]について
-
[解決済み] selectタグのngModelの変更を検出する方法(Angular 2)?
-
[解決済み] SVG のテキスト要素の幅を取得する
-
[解決済み] JavaScriptでクエリ文字列が存在するかどうかを確認するには?
-
[解決済み] async-await from functionを使用して非同期関数から値を返すには?重複
-
[解決済み] マウスオーバー時のマウスカーソルをアンカーのようなスタイルに変更する
-
[解決済み] データ追加時にdivの末尾まで自動スクロールさせるには?重複
-
[解決済み] ネストされたJSONオブジェクト - すべてに配列を使用しなければならないのか?