GLib(Gjs) Tips
# 最終更新日 2023.11.19
ユーザーディレクトリ
~/.config/user-dirs.dirs で指定されたディレクトリ名を取得
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; const dirs = { Desktop: GLib.UserDirectory.DIRECTORY_DESKTOP, Documents: GLib.UserDirectory.DIRECTORY_DOCUMENTS, Download: GLib.UserDirectory.DIRECTORY_DOWNLOAD, Music: GLib.UserDirectory.DIRECTORY_MUSIC, Pictures: GLib.UserDirectory.DIRECTORY_PICTURES, Public: GLib.UserDirectory.DIRECTORY_PUBLIC_SHARE, Templates: GLib.UserDirectory.DIRECTORY_TEMPLATES, Videos: GLib.UserDirectory.DIRECTORY_VIDEOS } for (let key in dirs) { let value = GLib.get_user_special_dir(dirs[key]); print(`${key}: ${value}`); }
システムディレクトリ
カレントディレクトリや一時ファイルディレクトリ等を得る
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; print(GLib.get_current_dir()); // 現在のカレントディレクトリ print(GLib.get_home_dir()); // ホームディレクトリ /* その他 get_system_config_dirs get_system_data_dirs get_tmp_dir get_user_cache_dir get_user_config_dir get_user_data_dir get_user_name get_user_runtime_dir */
環境変数
JavaScript 基本機能には無いので GLib に頼る
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; GLib.setenv('HOGE', 'hogehoge', false); // 環境変数のセット print(GLib.getenv('HOGE')); // 環境変数の取り出し for (let key of GLib.listenv()) { print(`${key}=${GLib.getenv(key)}`); // 環境変数の一覧 }
ファイルとディレクトリ
cp や mv を行うには Gio を使う、Gio を使うまでもない単純作業用
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; const DIRNAME = '日本語ディレクトリ'; const FILENAME = '日本語ファイル名.txt'; const CONTENTS = `一行目 に行目 3行目`; // mkdir コマンド、8 進数表記は 0o*) GLib.mkdir_with_parents(DIRNAME, 0o755); // test コマンド、ディレクトリが存在しているか調べる if (GLib.file_test(DIRNAME, GLib.FileTest.IS_DIR)) { print(`${DIRNAME} ディレクトリを作成しました`); } // cd コマンド、カレントディレクトリの移動 print('入ります'); GLib.chdir(DIRNAME); // pwd、現在のカレントディレクトリを標準出力に吐き出す print(GLib.get_current_dir()); // リダイレクト、JavaScript 文字列のままでも UTF-8 で出力される GLib.file_set_contents(FILENAME, CONTENTS); // 存在確認 if (GLib.access(FILENAME, 0o755)) { print(`${FILENAME} ファイルを作成しました`); } // ドットを使った特殊ディレクトリも対応 print('出ます'); GLib.chdir('..'); print(GLib.get_current_dir());
ファイル名リストの数値優先ソート
ようするに Nautilis の並び順と同じ数値優先ソート
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; const l = [ '40.txt', '200.txt', '001.txt', '2.txt', '03.txt', '123456.txt']; l.sort( (str1, str2)=> { let cmpstr1 = GLib.utf8_collate_key_for_filename(str1, -1); let cmpstr2 = GLib.utf8_collate_key_for_filename(str2, -1); if (cmpstr1 < cmpstr2) return -1; return 1; }); for (let s of l) print(s);
コマンドの実行、コマンド出力を得る
コマンド出力は Uint8Array で戻ることに注意
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; /** * コマンド出力不要なら、たとえば totem の起動等 */ GLib.spawn_command_line_async('totem'); /** * output にstdout、error に stderr が入る * 出力結果は Uint8Array なので変換が必要 * 存在しないコマンドでは例外になるが try catch では捕まえられない */ let [result, output, error, status] = GLib.spawn_command_line_sync('ls -l'); if (status == 0) { let dec = new TextDecoder(); let text = dec.decode(output); print(text); } else { print(`stderr\n${error}`); // ココには来ないかも }
ファイル名ユーティリティ
このコマンドでは実在の有無は関係ありません
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; const s = '/home/sasakima-nao/OM SYSTEM/OM-1 とパナライカ.jpg'; // ディレクトリ名 print(GLib.path_get_dirname(s)); //=> /home/sasakima-nao/OM SYSTEM // ファイル名のみ print(GLib.path_get_basename(s)); //=> OM-1 とパナライカ.jpg // 絶対パスチェック print(GLib.path_is_absolute(s)); //=> true // フルパス作成(区切り文字の有無を自動調節) print(GLib.build_filenamev(['/home/sasakima-nao/', '/H な画像', 'ヒヨドリ.jpg'])); //=> /home/sasakima-nao/H な画像/ヒヨドリ.jpg
URI 変換
このコマンドも実在の有無は関係ありません
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; // スキーム取得、実在は関係ないようだ let scheme = GLib.uri_parse_scheme('hoge://fuga.jp/'); print(scheme); //=> hoge // 第 3 引数を true にすると Unicode ドメイン対応になる let uri = GLib.uri_escape_string('日本語blog.jp', null, false); print(uri); //=> %E6%97%A5%E6%9C%AC%E8%AA%9Eblog.jp // 文字列に戻す let txt = GLib.uri_unescape_string(uri, null); print(txt); //=> 日本語blog.jp // パス名を URI に、ローカル(同一パソコン内)のファイルならホスト名は不要 uri = GLib.filename_to_uri('/home/sasakima-nao/コゲラ.jpg', null); print(uri); //=> file:///home/sasakima-nao/%E3%82%B3%E3%82%B2%E3%83%A9.jpg // 文字列に戻す let [pathName, hostName] = GLib.filename_from_uri(uri); print(pathName); //=> /home/sasakima-nao/コゲラ.jpg
リダイレクト
echo ほげ > gjs_write.txt ; cat < gjs_write.txt と同様なリダイレクトです。
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; const FILE = 'gjs_write.txt'; const TEXT = `出力では JavaScript 文字列のままイケます 入力は Uint8Array になりますので以下のように`; let result = GLib.file_set_contents(FILE, TEXT); // Write if (result) { print('Write Success'); } let [result2, contents] = GLib.file_get_contents(FILE); // Read if (result2) { let dec = new TextDecoder(); let text = dec.decode(contents); print(text); }
タイマー
timeout_add は g_timeout_add_full にバインドされているので注意 timeout_add(priority: Number(gint), interval: Number(guint), function)
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; let count = 0; let mainloop = new GLib.MainLoop(null, false); GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, ()=> { if (count === 10) { mainloop.quit(); return false; } print(count++); // true を戻すと継続 return true; }); mainloop.run();
日付けと時刻
JavaScript の Date を使ったほうがいいと思うけど GLib でも可能
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; let datetime = GLib.DateTime.new_now_local(); print(datetime.format("日付 %Y年%m月%d日\n時刻 %H:%M:%S"));
文字コード(cp932, utf8)変換
何度も書きますが Windows の文字コードは CP932 です、Shift-JIS ではありません iconv -l コマンドで出力される文字コードはすべて双方向で変換できます
#!/usr/bin/gjs -m import GLib from 'gi://GLib'; let [result2, contents] = GLib.file_get_contents('txt932.txt'); // Read let [u8arr, br, bw] = GLib.convert(contents, 'UTF-8', 'CP932'); let dec = new TextDecoder(); let text = dec.decode(u8arr); print(ByteArray.toString(text));