Paepoi » JavaScript Tips » Gjs, JXA, Node.js
Gjs, JXA, Node.js
# 最終更新日 2020.07.19
スタンドアロン(単独で利用できる)の JavaScript 実行環境での基本機能の覚書
UNIX 系(macOS 含む)のみで動作確認
スタンドアロン(単独で利用できる)の JavaScript 実行環境での基本機能の覚書
UNIX 系(macOS 含む)のみで動作確認
通称 | コマンド名 | 動作環境 | コア |
---|---|---|---|
Gjs | gjs | GNOME | SpiderMonkey |
JXA | osascript | macOS | JavaScriptCore |
Node.js | node | マルチ | V8 |
標準入出力
echo ほげ | gjs test.js のようなパイプ入力も考慮しました
/** * Gjs */ const GLib = imports.gi.GLib; // readline は自作してみた let readline = function(prpt) { // stdin=0 stdout=1 let channel = GLib.IOChannel.unix_new(0); let prefix = '端末入力'; if (channel.get_flags() == GLib.IOFlags.IS_READABLE) { prefix = 'パイプ'; } else { channel.write_chars(prpt, -1); } let [status, str_return] = channel.read_line(); let line = str_return.toString().trimEnd(); return [prefix, line]; } let [prefix, line] = readline('何か入力して Enter :'); print(`${prefix}から ${line} が渡されました`); /** * JXA (GNU readline 同様に使える) */ ObjC.import('readline'); ObjC.import('unistd'); let prefix = $.isatty(0) ? '端末入力' : 'パイプ'; let line = $.readline('何か入力して return :'); console.log(`${prefix}から ${line} が渡されました`); /** * Node.js */ const ReadLine = require('readline'); const Tty = require('tty'); let readline = ReadLine.createInterface({ input: process.stdin, output: process.stdout, terminal: false }); let [prpt, prefix] = Tty.isatty(0) ? ['何か入力して return :', '端末入力'] : ['', 'パイプ']; readline.question(prpt, (line)=> { console.log(`${prefix}から ${line} が渡されました`); readline.close(); });
ファイルの読み書き
Gjs は Gio を使ったほうがいいけどそれは別のページにて
/** * Gjs */ const GLib = imports.gi.GLib; const FILE = 'write_gjs.txt'; const TEXT = '日本語を書き込むよ\n改行もしてみるよ'; let result = GLib.file_set_contents(FILE, TEXT); // Write if (result) { print('Write Success'); } let [result, contents] = GLib.file_get_contents(FILE); // Read if (result) { print(contents.toString()); } /** * JXA */ ObjC.import('Cocoa'); const FILE = $('write_jxa.txt'); const TEXT = $('日本語を書き込むよ\n改行もしてみるよ'); let nil = $(); // Write let res = TEXT.writeToFileAtomicallyEncodingError(FILE, true, $.NSUTF8StringEncoding, nil); if (res) { console.log('Write Success!'); } // Read let s = $.NSString.alloc.initWithContentsOfFileEncodingError(FILE, $.NSUTF8StringEncoding, nil); console.log(s.js); /** * Node.js */ const FILE = 'write_node.txt'; const TEXT = '日本語を書き込むよ\n改行もしてみるよ'; let fs = require('fs'); fs.writeFile(FILE, TEXT, (err)=> { if (err == null) console.log('Write Success!'); }); fs.readFile(FILE, 'utf8', (err, content)=> { if (err != null) console.log(err); else console.log(content.trim()); });
起動パラメータ
Node.js は Python と同様なパラメータになる、他は全部パラメータのみの配列
/** * Gjs (1.52 からUNICODE 化されました) */ if (ARGV.length == 0) { print('No argv'); } else { for (let s of ARGV) { print(s) //print(decodeURIComponent(escape(s))); // under 1.52 } } /** * JXA */ function run(argv) { if (argv.length == 0) { console.log('No argv'); } else { for (let s of argv) { console.log(s); } } } /** * Node.js (実行ファイル名, スクリプトファイル名, argv[0], argv[1], ...) */ if (process.argv.length == 0) { console.log('No argv'); } else { for (let s of process.argv) { console.log(element); } }
環境変数
$HOME を表示する例
/** * Gjs */ const GLib = imports.gi.GLib; print(GLib.getenv('HOME')); /** * JXA */ ObjC.import('stdlib'); console.log($.getenv('HOME')); /** * Node.js */ console.log(process.env.HOME);
シェルコマンドの実行
ls -l の結果を得て表示する例
/** * Gjs */ const GLib = imports.gi.GLib; let output = GLib.spawn_command_line_sync('ls -l')[1]; print(output); /** * JXA */ let app = Application.currentApplication(); app.includeStandardAdditions = true; // alteringLineEndings オプション無しだと改行が CR に変換される let res = app.doShellScript('ls -l', {alteringLineEndings: false}); console.log(res); /** * Node.js */ const exec = require('child_process').exec; exec('ls -l', (err, stdout, stderr)=> { console.log(stdout); });
タイマー
setInterval, setTimeout はウエブブラウザからしか使えない と思ったら Node.js は使えるんだね
/** * Gjs (メインループが必要) */ const GLib = imports.gi.GLib; let count = 1; let mainloop = new GLib.MainLoop(null, false); GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, ()=> { if (count == 5) { mainloop.quit(); return false; } print(count); count ++; return true; }); mainloop.run(); /** * JXA */ ObjC.import('Cocoa'); let count = 1; let operation = $.NSBlockOperation.blockOperationWithBlock( function() { if (count == 5) timer.invalidate; console.log(count); count++; } ); let timer = $.NSTimer.timerWithTimeIntervalTargetSelectorUserInfoRepeats( 1, operation, 'main', null, true); $.NSRunLoop.currentRunLoop.addTimerForMode(timer, 'timer'); // 戻り値が表示されるので変数に入れる let r = $.NSRunLoop.currentRunLoop.runModeBeforeDate('timer', $.NSDate.distantFuture); /** * Node.js (ブラウザと同じ) */ let count = 1; let id = setInterval(()=> { if (count == 5) clearInterval(id); console.log(count); count++; }, 1000);
Copyright(C) sasakima-nao All rights reserved 2002 --- 2023.