今回は 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 屋のままなほうが幸せかも。