JScript シェル

via http://moz-addon.g.hatena.ne.jp/ZIGOROu/20071122/1195761296 (など)
気のせいか JScript シェルブームでしょうか。自分が使ってるのを晒してみよう。

基本は入力文字列を eval して、戻りがあれば表示する。コマンドプロンプトから実行すればなぜか↑↓キーで履歴が使える。

D:\scripts\js\ijscript>cscript //nologo ijsc.js
ijsc> var o = {n: 1, s: "a"}
ijsc> o
[object Object]
ijsc> o.n
1
ijsc> p
TypeError: 'p' は宣言されていません。

function は必要になった時にちょこちょこ追加している。
よくある表示系。

ijsc> print(o.s)
a
ijsc> dump(o)
n: 1
s: a

time() は処理時間の計測。Firebug のまね。sleep() はそのまま。

ijsc> time(1); sleep(1234); time(1)
1234ms

run() はプログラム実行。まず使わない。

ijsc> run('notepad')

create() で COM いじり。単に new ActiveXObject() とか入力するのがめんどいだけ。大文字が苦手。

ijsc> var excel = create('excel.sheet', {application: {visible: 1}})
ijsc> excel.activesheet.cells(1,1).value = 'foo'
foo
ijsc> excel.saveas('zzz')
True
ijsc> excel.application.quit()

files() でファイル名取得。正規表現でフィルタ。

ijsc> files('libs').join('\n')
D:\scripts\js\ijscript\libs\isbn.js
D:\scripts\js\ijscript\libs\zzz.js

ijsc> files('libs', /zzz/).join('\n')
D:\scripts\js\ijscript\libs\zzz.js

load() でライブラリ読み込み。

ijsc> load('libs/isbn.js')
ijsc> ISBN
[object Object]

ディレクトリ指定でそこにある js ファイルすべて。

ijsc> load('libs')
ijsc> Zzz
[object Object]

Web からも読み込みできる。ライブラリを試用するときとかに使う。

ijsc> "str".toSource()
TypeError: オブジェクトでサポートされていないプロパティまたはメソッドです。
ijsc> load('http://coderepos.org/share/browser/lang/javascript/Object.toSource/lib/Object/toSource.js?format=raw')
ijsc> "str".toSource()
(new String("str"))

proxy() でプロキシ指定。うちの会社からは串を通さないと出れません…。監視してるらしいよ。こわいね。

ijsc> proxy({host: 'proxy.example.com:8080', userid: 'foo', password: 'bar'})

quit() で終了するけど、めんどいので Ctrl-C で。

ijsc> quit()

引数で読み込むファイル名やディレクトリ、URL を指定できる。ユニットテストするときによく使ってる。
−q はシェルモードにならずに終了。

D:\scripts\js\ijscript>cscript //nologo ijsc.js -q libs libs\tests\lib\test libs\tests\tests.js
OK - [f, ]
...
OK - [eq, 978-1-59059-727-9, 978-1-59059-727-9]
OK: 37, NG: 0, 100
D:\scripts\js\ijscript>

−e でワンライナー。SAPI.SpVoice すごいね(ネタ元 ZIGOROu さん)

D:\scripts\js\ijscript>cscript //nologo ijsc.js -e "new ActiveXObject('SAPI.SpVoice').Speak('JScript++')"

ソースは読まないほうがいいです。

// ijsc.js

(function() {
  var _p = {
    sin: WScript.StdIn,
    sout: WScript.StdOut,
    serr: WScript.StdErr,
    times: {},

    error: function(e) {
      _p.serr.WriteLine(
        (e instanceof Error) ? e.name + ': ' + e.message : e);
    },

    read_f: function(path) {
      if (!_p.fso)
        _p.fso = WScript.CreateObject('Scripting.FileSystemObject');
      var src = "";
      if (_p.fso.FolderExists(path)) {
        for (var fs = files(path, /\.js$/), n = 0, m = fs.length; n < m; ++n)
          src += _p.read_f(fs[n]);
      } else {
        var f = _p.fso.OpenTextFile(path, 1, false);
        src = f.ReadAll();
        f.Close();
      }
      return src;
    },

    read_u: function(url) {
      if (!_p.http)
        _p.http = WScript.CreateObject('WinHttp.WinHttpRequest.5.1');
      if (_p.proxy)
        _p.http.SetProxy(0, _p.proxy.host);
      _p.http.Open('GET', url);
      _p.http.Send();
      while (true) {
        switch (_p.http.status) {
          case 200:
            return _p.http.responseText;
          case 407:
            if (!_p.proxy || !_p.proxy.userid || !_p.proxy.password)
              throw new Error(_p.http.statusText);
            _p.http.SetCredentials(_p.proxy.userid, _p.proxy.password, 1);
            _p.http.Send();
            if (_p.http.status == 407)
              throw new Error(_p.http.statusText);
            break;
          default:
            throw new Error(_p.http.statusText);
        }
      }
    },

    apply: function(obj, args) {
      for (var k in args) {
        try {
          switch (typeof obj[k]) {
            case 'function':
            case 'unknown':
              if (args[k] == null) {
                obj[k]();
              } else {
                obj[k](args[k]);
              }
              break;
            case 'object':
              _p.apply(obj[k], args[k]);
              break;
            default:
              obj[k] = args[k];
              break;
          }
        } catch (e) {
          _p.error(e);
        }
      }
    }
  };

  function print(val) { _p.sout.WriteLine(val) }
  function quit(code) { WScript.Quit(code) }
  function proxy(proxy) { _p.proxy = proxy }
  function sleep(ms) { return WScript.Sleep(ms) }

  function read(file) {
    return file.match(/^http(?:s?):\/\//) ? _p.read_u(file) : _p.read_f(file);
  }

  function dump(obj) {
    for (var k in obj)
      _p.sout.WriteLine(k + ': ' + obj[k]);
  }

  function create(name, args) {
    var o = WScript.CreateObject(name);
    if (args) {
      if (args instanceof Array) {
        for (var i = 0, m = args.length; i < m; ++i)
          _p.apply(o, args[i]);
      } else {
        _p.apply(o, args);
      }
    }
    return o;
  }

  function files(dir, re) {
    if (!_p.fso)
      _p.fso = WScript.CreateObject('Scripting.FileSystemObject');
    var r = [];
    for (var d = _p.fso.GetFolder(dir), p, e = new Enumerator(d.files);
        !e.atEnd(); e.moveNext()) {
      p = e.item().path;
      if (!re || p.match(re))
        r.push(p);
    }
    return r;
  }

  function time(key) {
    if (_p.times[key]) {
      _p.sout.WriteLine((new Date).getTime() - _p.times[key].getTime() + 'ms');
      delete _p.times[key];
    } else {
      _p.times[key] = new Date;
    }
  }

  function run(cmd) {
    if (!_p.shell)
      _p.shell = WScript.CreateObject('WScript.Shell');
    _p.shell.Run(cmd);
  }

  with ({n: 0, m: 0, item: "", fquit: false, feval: false}) {
    for (n = 0, m = WScript.Arguments.length; n < m; ++n) {
      item = WScript.Arguments.Item(n);
      if (item.match(/^-(\w+)$/)) {
        if (RegExp.$1 == 'q') {
          fquit = true;
        } else if (RegExp.$1 == 'e') {
          feval = true;
          fquit = true;
        }

      } else if (feval) {
        eval(item);
        feval = false;

      } else {
        eval(read(item));
      }
    }

    if (fquit)
      return;
  }

  while (true) {
    _p.sout.Write('ijsc> ');
    _p.line = _p.sin.ReadLine();

    try {
      if (_p.line.match(/^load\((.*)\)$/)) {
        eval(read(eval(RegExp.$1)));

      } else {
        _p.res = eval(_p.line);
        if (typeof _p.res != 'undefined')
          _p.sout.WriteLine(_p.res);
      }

    } catch (_e) {
      _p.error(_e);
    }
  }
})();