投稿者「sasakima-nao」のアーカイブ

Linux でファイル名に改行コードを入れる

今日は Linux のファイル名で遊ぶよ。

ファイル名に日本語を使う人は改行位置が気になることがあるよね。
英語ならワードラップで勝手にイイ感じになるのに不公平だ。

rename01

ここは「魔法少女」の所で改行してくれると綺麗に見えるのに…
みたいなことを思う変人がいるかどうかは知らないけれど。
実はファイル名に改行コードを普通に入れられるんだよ。

mv コマンドの変更先ファイル名をダブルクォーテーションで始める。
改行させたいところで Enter して改行する、クォーテーションを閉じる。

$ mv 魔法少女まどか☆マギカ.jpg "魔法少女
> まどか☆マギカ.jpg"

rename02

ls での表示が ? になった。
0x0A なので改行するかなと思ったけど ? を表示なんだ。
Nautilus ではどうなるんだろう。

rename03

見事狙った位置で改行されるようになりました。
いや、ファイル名に改行コードなんて入れて問題無いのか?

rename04

eog, Firefox でも問題なく表示できるけど Chrome は駄目でした。
少し調べるとサーバーアップロードとかにも一部引っ掛るみたい。
普通は文字列以外がファイル名にあるなんて思わないもん。

でも外付け HDD なんかにコピーするのは問題無し。
つまり自分のコレクションに使う分にはやってもよさそう。

というより。
端末でこうすると 0x0A が入ってしまうので注意しよう。
気が付かずにファイル名に入れてしまい「何か変」にならないようにNE!

Linux でエロ本

今日は Linux でエッチな本を楽しむ方法の紹介だよ。
CBR, CBZ と言っても HONDA のバイクじゃないよ。

エッチなサイトを廻っているとたまに D○M のサンプル本が置いてあるよね。
紳士であるみんなはついつい zip を落としてしまうよね。
男の子だもん、しかたがないよ。
ということで、そのまま拡張子を *.cbz に変更してみよう。

ero1

あれ?圧縮したまま Nautilus でサムネイル表示されちゃった。
コレをそのまんまドキュメントビューアー(evince)で開くよ。

ero2

なんと今の Linux では何も入れなくてもエロ本を楽しめちゃう。
ファイルが一つで中身がサムネイルで解るので管理も簡単。
サムネイルを表示したら困るなんて女々しい男はいないよね。
まさしく男の中の男のための OS でありました。

でも evince だと快適機能が何もない、でも大丈夫。
世界中の男子なプログラマーが MComix ってアプリを作っている。
コイツなら見開きページもバッチリさ(スクショは自粛)
もうプロパティからデフォルトアプリにしてしまえ。

ero3

いや、本当は自作か自分でスキャンしたもの用なんでしょうけど。
スマホや iPad の観覧アプリも結構あるんだよ。

ちなみに MComix は Python 製です、PyGtk ですが。
もし「もっとこう…」とか思ったらソースを参考に自作してみよう。
/usr/lib/python2.7/site-packages/mcomix にあるよ。

PyGObject ならおじさんがチップスを書いているよ。
PyGObject Tips – L’Isola di Niente
せっかく作り変えたけどアクセス少なくてションボリだよ。

GFileMonitor

最近 GUI をやっていない。
コマンドラインばかりじゃつまんない。

で、実用的かもしれないディレクトリ内容の変更を監視し出力するウインドウを。
いや、随分前にやって上手くいかなかったのだが原因がやっと解ったので。
GUI は C では面倒すぎなので Python で。

#!/usr/bin/env python3

"""
    $HOME を監視するサンプル
"""

from gi.repository import Gtk, Gio, GLib

class Win(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.view = Gtk.TextView()
        self.view.set_editable(False)
        sw = Gtk.ScrolledWindow()
        sw.add(self.view)
        self.add(sw)
        #
        # ファイル監視も同様、現在存在していない場合でも監視してくれる
        #f = Gio.File.new_for_path(GLib.get_home_dir() + "/test.txt")
        f = Gio.File.new_for_path(GLib.get_home_dir())
        #
        # GFileMonitor は他メソッドで使わなくても必ずアトリビュートにする
        # しないと __init__ 抜けた時点で破棄されてしまう
        #
        self.monitor = f.monitor(Gio.FileMonitorFlags.NONE)
        #self.monitor = f.monitor(Gio.FileMonitorFlags.SEND_MOVED)
        self.monitor.connect("changed", self.on_monitor)
        # self
        self.connect("delete-event", Gtk.main_quit)
        self.resize(300, 200)
        self.show_all()

    def on_monitor(self, monitor, f, other_f, event):
        """
            ディレクトリ監視は隠しファイルの変更も感知します
            ( /.bash.history 等 )
        """
        buf = self.view.get_buffer()
        s = f.get_path()
        if event == Gio.FileMonitorEvent.CHANGED:
            # ファイルの内容が変更された時
            buf.insert_at_cursor("CHANGED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.CHANGES_DONE_HINT:
            # ファイルの情報が変更された時
            buf.insert_at_cursor("CHANGES_DONE_HINT: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.DELETED:
            # 削除(リネーム、移動含む)された時
            buf.insert_at_cursor("DERETED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.CREATED:
            # 作成(リネーム、移動含む)された時
            buf.insert_at_cursor("CREATED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.ATTRIBUTE_CHANGED:
            # パーミッションが変わった時
            buf.insert_at_cursor("ATTRIBUTE_CHANGED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.PRE_UNMOUNT:
            # Gio.FileMonitorFlags.WATCH_MOUNTS 指定時のみ
            buf.insert_at_cursor("PRE_UNMOUNT: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.UNMOUNTED:
            # Gio.FileMonitorFlags.WATCH_MOUNTS 指定時のみ
            buf.insert_at_cursor("UNMOUNTED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.MOVED:
            # Gio.FileMonitorFlags.SEND_MOVED 指定時のみ
            buf.insert_at_cursor("MOVED: {0}\n".format(s))
        # Gio.FileMonitorFlags.WATCH_MOUNTS 指定時に、あれ?
        if other_f:
            buf.insert_at_cursor("other: {0}\n".format(f.get_path()))

Win()
Gtk.main()

gfilemonitor

で、結論。
GFileMonitor のインスタンスは self のアトリビュートにする必要がある。

今迄は他メソッドから参照する必要が無いものは self にはくっつけなかった。
すると全然シグナルが飛んでこない、バグだとずっと思っていた。
しかし今日 self を付けただけであら不思議。

よく考えたらガベージコレクションだから当然である。
GUI 部品なら親ウインドウにくっついているのだから何かしら参照がある。
しかしメインループで動いているだけの部品はどこからも参照されていない。
結果ガベージコレクタの破棄対象に、何かで参照しないといけない。

PyGObject を作っている皆様、コッソリ疑っていてごめんなさい。

もしかしてアレも、と思い付くのがチラホラ。

しかしファイル監視は存在しないファイルを指定してもいいんだね。
新規作成で CREATE と CHANGES_DONE_HINT のシグナルが飛んでくる。
CHANGES_DONE_HINT はちょっとうっとうしい。

それと $HOME を監視したまま gnome-terminal を終了すると解るけど。
~/.bash_history とかの隠しファイルへの書き出しにも反応する。
コレはハンドラ側で見分け等をする、でいいのかな。

gfilemonitor2

SEND_MOVED 指定も試してみた、なるほどそうなるか。
ディレクトリ移動だと結局 DELETED になる、リネームしか意味が無い。
しかし *other_file 引数は何だろう?

それよりリネーム後のファイル名が得られないと困るんだが。
バ…いやいや、コレも手段が悪いだけなのかもしれないし。
というか、使い道が思いつかないしどうでもいいかなと。

おまけで、GDataOutputStream での上書き保存のみ。

#!/usr/bin/env python3
 
from gi.repository import Gio

f = Gio.file_new_for_path("output_stream.txt")
fstream = f.replace("", False, Gio.FileCreateFlags.NONE)
dstream = Gio.DataOutputStream.new(fstream)
dstream.put_string("BKB BKB")
fstream.close()

output_stream

OutputStream ってこんなことをやっていたの!
当然の話だが Gedit の上書き保存もまったく同じ。
いやいや、監視してみると色々面白いことが解るNE!

\033[

今日の覚書

【第十二回】エスケープシーケンス(2) – あらほりLinuxメモ

#!/bin/sh

# \033[数値A で戻りたい行数の数値
# \033[0J    でカーソル以降の行を削除

echo いくぞー

for s in いーち にー さーん だぁー!
do
    sleep 1
    printf "\033[1A\033[0J"
    echo $s
done

daa

なるほど、使い道は微妙だけど。
もっと更新してほしいな、忙しいのだろうけど。

1 ページ前の色分けはも含め C や Python からも使えるのね。
しかし cmd.exe はそもそも色分けができないだろ、なんだが。
エスケープシーケンス

Python

#!/usr/bin/env python3

print("\033[32m緑色おおおお");
print("\033[31m赤色おおおお");
# 戻す
print("\033[39m", end='');

C (glib)

#include <glib.h>

int
main (int argc, char* argv[]) {

    g_printf("\033[32m緑色おおおお\n");
    g_printf("\033[31m赤色おおおお\n");
    // 戻す
    g_printf("\033[39m");
    return 0;
}

033

コッチは警告表示で赤で出力とか便利そう。
sh で探して C, Python も使えたので得した気分。

Bash Increment

シェルスクリプトの変数って ++ でインクリメントできたんですね。
Bash – シェルのループ処理内でのインクリメント – Qiita
これも凄いがコメント(一番下)がもっと凄い。

while (( count < 10000 ));

こんなのまでできたのか、マジで速いし。

試すと (( count– )) で普通にデクリメントするね。
Ramen Timer for Ubuntu sh | PaePoi
これを使えば seq を逆順ソートとかしていたラーメンタイマーを

#!/bin/sh
 
# カップラーメン用にどうぞ
 
read -p 完成までの残り時間を秒で指定: count
echo 止めるには Ctrl+C
 
while (( count > 0 )); do
    printf "残り%02g分%02g秒  \r" $(( count / 60 )) $(( count % 60 ))
    (( count-- ))
    sleep 1
done
echo できあがりぃ?

inc

速いうえに圧倒的に可読性の良いコードになりました。
C と似た感じにするだけで随分と違うものだ。
分と秒を分けるのはコレでいいです。

Fedora の sh (Bash) のみでの動作確認ですが。
シェルが違う人は bash 指定に書き換えしてね。

しかし覚書を qiita に書き込んでいる人達はなんだろう?
それよりこういう有用なコードを詰め込んだサイトを作ってほしいな。
覚書色々 – L’Isola di Niente
自力でチビチビ作っているんだけどまだ少ないよな。。。