タグ別アーカイブ: Node.js

Node.js Gjs Async

今回は Node.js でシェルコマンドを使う方法を探してみる。

Node.jsからシェルコマンドを実行する – BppLOG

あらこんな簡単に、Gjs と違って日本語で見つかるのは羨ましい。
exec で非同期になるのかフムフム。

…って非同期通信だよね、mainloop いらないの?
関数を抜けた後でも callback handler を保持しなきゃいけないよね??
本当は非同期ではないのかも、実験だ!

#!/usr/bin/env node

const exec = require('child_process').exec;

exec('eog', (err, stdout, stderr) => {
    if (err) { console.log(err); }
    console.log('callback');
});

console.log('__done__');

GUI のほうが動作が解りやすいので eog を立ち上げてみる、Linux の長所だね。
macOS では Kivy とか PyObjC を使えばいいと思う。
結果は見事に __done__ のほうが先に表示、eog 終了時に callback 表示となった。
見事に関数を抜けているね、本当に非同期で動いていことを確認できた。
どうやっているの?

っっって。
よく見たら child_process というモジュール名じゃないか。
つまり Subprocess で動かしているだけってことかも。
Gjs で同様に動く処理を考えてみる、えぇと…

#!/usr/bin/gjs

const Gio = imports.gi.Gio;
const ByteArray = imports.byteArray;

let subprocess = Gio.Subprocess.new(["ls", "-la"], Gio.SubprocessFlags.STDIN_PIPE);
let barray = new ByteArray.ByteArray();
subprocess.communicate_async(barray, null, function(source_object, res) {
    let istream = source_object.get_stdout_pipe();
    let dstream = Gio.DataInputStream.new(istream);
    for (;;) {
        let [s, l] = dstream.read_line_utf8(null);
        if (s == null) break;
        print(s);
    }
});
print('__done__');

コチラは上記リンク先同様になるよう ls -la の結果を表示の例。
うん、__done__ のほうが先に表示されるので非同期になっている。
つまり Node.js の exec は純粋な非同期ではなく子プロセスってことみたい。

初心者には意味不明?んなモン知るか!!!

いやいや、Node.js をやったおかげで GSubprocess の新たな使い方を知ってしまった。
これで Gjs プログラミングが捗るゾイ!

Node.js stdin

せっかく Node.js を入れたので覚書ページに追記してみようと考えた。

ちなみに筆者が今まで Node.js を嫌っていた理由、検索すると。。。
npm でインストール、インストール、インストール、インストール、イン(以下略
ばかりでゲンナリしたからです。

そうか、Node.js でプログラミングってインストールすることなのか!
っっって、アホか!!!
実は Python でも pip を使ったことが無い、てか必要になったことが無い。
つまり何もインストールせずに使える Gjs や JXA のほうがいいや、ということで。

Gjs があるのに何故こんなのを作る人がいるのかまったく理解できないし。
GitHub – WebReflection/node-gtk: GNOME Gtk+ bindings for NodeJS

悪口ばかり書いてもしょーがないので本題。
そんなこんなで、素の Node.js だけで何ができるか試してみよう。
とりあえず stdin はどうやるのだろう。

readline – Node.js v0.4.12 Manual & Documentation

readline モジュールがあるのか、コピペしてみよう。

なんじゃそりゃ!

node.js – How to read from stdin line by line in Node – Stack Overflow

createInterface の引数は JSON でってことなのね。
公式が間違えてどうすると思ったけど v0.4 って古いにもほどがあるページだった。
v6 の公式ドキュメントはしっかり JSON で ES6 フル活用になっている。
英語ですが。

Readline | Node.js v6.11.1 Documentation

isatty も使えるようだ。
それならパイプからの入力との振り分けも簡単だな。

#!/usr/bin/env node

const ReadLine = require('readline');
const Tty = require('tty');

let readline = ReadLine.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: false
});

let prompt = "";

if (Tty.isatty(0))
    prompt = "May I ask your name?\n> ";

readline.question(prompt, function(answer) {
    console.log(`Hello ${answer}`);
    readline.close();
    //process.stdin.destroy();
});

Gjs 風にしてみました。

terminal: false を入れないとパイプで渡した文字列が表示されるので注意。
readline.close() しないと readline が終了しない場合があるので注意。
process.stdin.destroy() はいらないみたい。

あれ?意外に面白そうだぞ Node.js も。