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));