今回は Gjs で標準入力とパイプ入力の振り分けをやってみよう。
ちなみに Python だと標準の os モジュールだけで可能。
#!/usr/bin/env python3
import os
if os.isatty(0):
# stdin
s = input("何か入力してください >")
print("[{0}]が入力されました".format(s))
else:
# pipe
with os.fdopen(0) as f:
s = f.read()[:-1]
print("[{0}]がパイプから渡されました".format(s))
コレと同様の動作ができるものを Gjs で作りたいということで。
Gjs は当然 GLib を使う、しかし GLib に isatty 関数は無い。
そういえば Gjs は stdout で行末から入力させる簡単な手段も無い。
よく考えたら標準入力も、Python に対し Gjs は print 以外は何もない。
これらを全部 GLib で行う必要がある。
#!/usr/bin/gjs
const GLib = imports.gi.GLib;
let channel = GLib.IOChannel.unix_new(0)
if (channel.get_flags() == GLib.IOFlags.IS_READABLE) {
/* -- Pipe -- */
[res, str_return] = channel.read_to_end();
// byte to string
let s = str_return.toString();
// Remove '\n'
s = s.slice(0, -1);
print("[" + s + "]がパイプから渡されました");
} else {
/* -- stdin -- */
// Input
channel.write_chars("何か入力してください >", -1);
// Flush Console
channel.shutdown(true);
// readline
let in_channel = GLib.IOChannel.unix_new(1);
[res, str_return] = in_channel.read_line();
// byte to string
let s = str_return.toString();
// Remove '\n'
s = s.slice(0, -1);
print("[" + s + "]が入力されました");
in_channel.shutdown(true);
}
GIOChannel だけでなんとかなった。
Gio を使う別の手段も色々あるけどコレが一番単純な手段だと思う。
正しいかどうかは解らないけど動けばいいんだよ。
g_io_channel_shutdown
でコンソール表示をフラッシュする必要に気が付くまで少し、いやかなり時間が掛かった。
コレを呼ぶまで何一つリアクションしないツンデレなコンソールに萌え…(嘘です
使っているライブラリが同じなので PyGObject で書き換えても動く。
というか PyGObject で書いて変換したのは内緒だよ。
だって PyGObject の例外表示のほうが桁違いに親切なんだもん。
しかし戻り値が配列(タプル)になるという仕様は Python と同じなのね。
これはある程度 Python の経験がある人でないと理解に苦しむと思うのですが。
現状ではそんな人しか Gjs を使うという選択はしないので問題ないけど…
それにしても中括弧やセミコロンだけでなく何もかもが面倒臭い。
うーん、やっぱり Python 屋のままなほうが幸せかも。
