もぐてっく

人は1つ歳をとるたび、1ビットづつ大きくなれると信じてた。

TL内を検索するmikutterプラグインを作ったよ

何これ?

TL内の文字列検索を実現するプラグインです。

「くぽぉwwwww相変わらず○○殿のネタ振りは流石でござるなwwそれでは某もインターネットダジャレおじさんとして皆に手本を見せねばなりませぬのwwwではここは『ゴマ豆腐』など・・・いやいや、もう一つひねりを加えて『PDドライブ』はいかがか?wwwふむ。少々の隙もあり、皆のツッコミも期待できる我ながら名回答でござるなwwwwさて、まずはお題をリツイート・・・あれ?どこ行ったでござるか???お題ツイート殿~?」

って時に便利です。

インストール

GitHubからzipファイルをダウンロードして適当なディレクトリに展開して下さい。

https://github.com/moguno/mikutter-find-tl

※mikutterプラグインマネージャ"Packaged"で"moguno"を検索してインストールするのもおすすめです。

使い方

TLのメッセージを右クリックして、メニューから「TL検索」を選択してください。

f:id:moguno:20160517101716p:plain

TLの上部に検索ボックスが出るので、探したい文字列を入力してください。
文字列を含むメッセージがTLの上部に出てくるハズです。

f:id:moguno:20160517101731p:plain

TL内検索コマンドをショートカットにアサインすると便利です。

設定

TL検索

f:id:moguno:20160517102059p:plain

  • マッチしたツイートのスタイル

検索にマッチしたメッセージのフォントと背景色を設定します。

Windows 10 Insider Previewの"Bash on Ubuntu on Windows"をハンズオン!

とうとうWindowsでもLinuxっぽいサブシステムがサポートされるということで、早速Insider Previewビルド14316を触ってみました!
(14316が配信されてからウチに降ってくるまで3日のタイムラグがあって、待ってる間約2分周期でWindowsアップデートを確認してたので眠いです。)

前情報によるとコンソールアプリはだいたい動く。Xのクライアントアプリも動くっぽいってことで、今回はちょっと意地悪にカーネルに近い部分を見ていこうと思います。

/devを見てみる

一部情報が取れないファイルがいますが、こんな感じでした。

root@localhost:~# ll /dev
ls: cannot access /dev/tty0: Invalid argument
ls: cannot access /dev/adss: Operation not permitted
total 7
drwxr-xr-x 2 root root    0 Apr 10 01:53 ./
drwxrwxr-x 2 root root    0 Jan  1  1970 ../
?????????? ? ?    ?       ?            ? adss
drwxr-xr-x 2 root root    0 Apr 10 01:53 block/
-rwxr--r-- 2 1000 1003    0 Apr 10 01:53 fb0*
drwxr-xr-x 2 root root    0 Apr 10 01:53 input/
crw------- 1 root 1007 0, 0 Apr 10 01:53 kmsg
?--------- 0 root root    0 Jan  1  1970 null
crw-rw-rw- 1 root tty  5, 2 Apr 10 01:53 ptmx
drwxr-xr-x 2 root root    0 Apr 10 01:53 pts/
crw-rw-rw- 1 root root 1, 8 Apr 10 01:53 random
lrwxrwxrwx 2 root root    0 Apr 10 01:53 shm -> /run/shm
crw--w---- 1 1000 tty  5, 0 Apr 10 01:53 tty
?????????? ? ?    ?       ?            ? tty0
crw-rw-rw- 1 root root 1, 9 Apr 10 01:53 urandom
crw-rw-rw- 1 root root 0, 0 Apr 10 01:53 zero
root@localhost:~#

ブロックデバイスは空。

root@localhost:~# ll /dev/block/
total 1
drwxr-xr-x 2 root root 0 Apr 10 01:55 ./
drwxr-xr-x 2 root root 0 Apr 10 01:55 ../
root@localhost:~#

次にイベントデバイス。お、マウスが見えてますね。

root@localhost:~# ll /dev/input/
total 5
drwxr-xr-x 2 root root 0 Apr 10 01:56 ./
drwxr-xr-x 2 root root 0 Apr 10 01:56 ../
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event0*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event1*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event2*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event3*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event4*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event5*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 mice*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 mouse0*
root@localhost:~#

早速試してみるも権限なし。残念。

root@localhost:~# cat /dev/input/mice
cat: /dev/input/mice: Operation not permitted
root@localhost:~#

ちなみに、フレームバッファ/dev/fb0も同様にダメでした。

root@localhost:~# echo 1 > /dev/fb0
bash: echo: write error: Operation not permitted
root@localhost:~#

マウントされてるファイルシステムを見てみる

各種仮想ファイルシステムがマウントされてます。

root@localhost:~# mount
rootfs on / type rootfs (ro,relatime)
tmpfs on /dev type tmpfs (rw,seclabel,nosuid,relatime,mode=755)
devpts on /dev/pts type devpts (rw,seclabel,relatime,mode=600)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,seclabel,relatime)
root@localhost:~#

/procを見てみる

デバイスドライバが追加する諸々がないのとプロセス数が少ないのとで、かなりシンプルですね。

root@localhost:~# ll /proc
total 4
dr-xr-xr-x 1 root root 0 Apr 10 01:21 ./
drwxrwxr-x 2 root root 0 Jan  1  1970 ../
dr-xr-xr-x 1 root root 0 Apr 10 02:02 1/
dr-xr-xr-x 1 root root 0 Apr 10 02:02 2/
dr-xr-xr-x 1 root root 0 Apr 10 02:03 64/
-r--r--r-- 1 root root 0 Apr 10 01:21 cmdline
-r--r--r-- 1 root root 0 Apr 10 01:21 cpuinfo
-r--r--r-- 1 root root 0 Apr 10 01:21 filesystems
-r--r--r-- 1 root root 0 Apr 10 01:21 interrupts
-r--r--r-- 1 root root 0 Apr 10 01:21 meminfo
lrwxrwxrwx 1 root root 0 Apr 10 01:21 mounts -> self/mounts
lrwxrwxrwx 1 root root 0 Apr 10 01:21 net -> /proc/self/net/
lrwxrwxrwx 1 root root 0 Apr 10 01:21 self -> /proc/64/
-r--r--r-- 1 root root 0 Apr 10 01:21 stat
dr-xr-xr-x 1 root root 0 Apr 10 01:21 sys/
-r--r--r-- 1 root root 0 Apr 10 01:21 uptime
-r--r--r-- 1 root root 0 Apr 10 01:21 version
root@localhost:~#

/proc/cpuinfoでCPUの情報がちゃんと取れてます。

root@localhost:~# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      :        Intel(R) Core(TM) i7-3667U CPU @ 2.00GHz
stepping        : 9
microcode       : 0xffffffff
cpu MHz         : 2494.000
cache size      : 256 KB
physical id     : 0
siblings        : 1
core id         : 0
cpu cores       : 1
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 6
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx rdtscp lm pni pclmulqdq monitor ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave osxsave avx rdrand
bogomips        : 4988.00
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:
root@localhost:~#

/proc/sys/kernel/osreleaseを見てみます。
ちゃんとMS製を名乗ってますねw

root@localhost:~# cat /proc/sys/kernel/osrelease
3.4.0-Microsoft
root@localhost:~#

ファイルシステムを見ると結構充実してますね。

root@localhost:~# cat /proc/filesystems
nodev      sysfs
nodev      rootfs
nodev      bed
nodev      proc
nodev      tmpfs
nodev      binfmt_misc
nodev      debugfs
nodev      sockfs
nodev      usbfs
nodev      pipefs
nodev      anon_inodefs
nodev      devpts
ext3
ext2
ext4
nodev      ramfs
nodev      hugetlbfs
vfat
msdos
iso9660
fuseblk
nodev      fuse
nodev      fusectl
yaffs
yaffs2
nodev      mqueue
root@localhost:~#

iso9660fuseが気になるので試してみます。

fuseを使ってみる

とりあえずデバイスファイルがないので作成。

root@localhost:~# mknod fuse c 10 229
root@localhost:~# ll fuse
ls: cannot access fuse: No such file or directory
root@localhost:~#

ダメでした。

ISOファイルをマウントしてみる

root@localhost:~# mount -o bind -t iso9660 /mnt/c/Users/mogun/Downloads/archlinux-2016.04.01-dual.iso /media/
root@localhost:~# mount
/mnt/c/Users/mogun/Downloads/archlinux-2016.04.01-dual.iso on /media type none (rw,bind)

お!行けた?

root@localhost:~# ls -l /media/
total 0
root@localhost:~#

かなり残念。見えませんでした。
この後、Windowsを再起動してもisoのマウントは解除されず。
/etc/mtab(中身は空)を削除すると復旧しました。

initの実力とやらをみてみる

Windows起動時にinitの初期ルーチンが動いてデーモンが動くと便利です。お手軽にrc.localが動くか試してみます。

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

echo "test" > /tmp/test

exit 0

リブートするも/tmp/testは作成されず。残念。

sshサーバを動かしてみる

これが動けばmsys2でやってた「WindowsなのにsshしたらLinuxっぽい」環境が誕生します。

まず、足りて無いディレクトリを作ります。

root@localhost:~# mkdir /var/run/sshd
root@localhost:~# chmod 755 /var/run/sshd/

それからsshdを起動するも、デーモンは常駐せず。
デバッグモードで挙動を見てみます。

root@localhost:~# /usr/sbin/sshd -d
・・・
Connection from 127.0.0.1 port 49811 on 127.0.0.1 port 22
debug1: Client protocol version 2.0; client software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 pat OpenSSH_6.6.1* compat 0x04000000
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
chroot("/var/run/sshd"): Invalid argument [preauth]
debug1: do_cleanup [preauth]
debug1: monitor_read_log: child log fd closed
debug1: do_cleanup
debug1: Killing privsep child 104
debug1: audit_event: unhandled event 12
root@localhost:~#

どうもchrootが動いてないのがダメっぽいですね。残念。

擬似端末ってどうなのかしら

sshdで擬似端末の扱いも見たいと思ってたんですが作戦失敗。シンプルなtelnetdで試すことに。
inetutils-inetdとtelnetdをインストールしました。

straceで観察しつつ接続してみます。

[pid    51] open("/dev/ptmx", O_RDWR)   = 3
[pid    51] statfs("/dev/pts", 0x7ff5fffee140) = -1 EPERM (Operation not permitted)
[pid    51] statfs("/dev/", 0x7ff5fffee140) = -1 EPERM (Operation not permitted)
[pid    51] close(3)                    = 0
[pid    51] open("/dev/ptyp0", O_RDWR)  = -1 ENOENT (No such file or directory)
[pid    51] write(0, "telnetd: getpty: No such file or"..., 47) = 47

Unix98、BSD方式共にコケて諦めてますね。ぐぅ残念。

デーモンが動くかみてみる

こんなスクリプトを書いてデーモンになるか試してみました。

Process.daemon

loop {
        sleep 1
        open("/tmp/a.txt", "a") { |fp|
                fp.puts "test"
        }
}

おお、a.txtのサイズが増えていきます。成功です。

root@localhost:~# ll /tmp/a.txt
-rw-rw-rw- 1 root root 160 Apr 10 02:52 a.txt
root@localhost:~# ll /tmp/a.txt
-rw-rw-rw- 1 root root 170 Apr 10 02:52 a.txt

でも、Bash on Ubuntu on Windowsのウインドウを閉じるとデーモンになったrubyも死にますね。

SysV IPCを試してみる

root@localhost:~# ipcs

kernel not configured for shared memory

kernel not configured for semaphores

kernel not configured for message queues

root@localhost:~#

おっと。サポートされていない様です。最近のアプリでは使わないんですかね?
今業務で保守してるソフトはSysV IPCバリバリなので、Windows移植の話が来たら全力で蹴ろうと思います。

その他

なんとなくlsofでbashが開いてるファイルを確認してみた

root@localhost:~# lsof | grep sh
bash     43 root  cwd   unknown                                 /root (stat: No such file or directory)
bash     43 root  rtd   unknown                                 /proc/43/root (readlink: No such file or directory)
bash     43 root  txt       REG    0,0 1021112 1970324836978220 /bin/bash
bash     43 root  mem       REG    0,0                     3628 /bin/bash (path inode=1970324836978220)
bash     43 root  mem       REG    0,0                   288340 /lib/x86_64-linux-gnu/libnss_files-2.19.so (path inode=1970324837262932)
bash     43 root  mem       REG    0,0                   288552 /lib/x86_64-linux-gnu/libnss_nis-2.19.so (path inode=1970324837263144)
bash     43 root  mem       REG    0,0                   288484 /lib/x86_64-linux-gnu/libnsl-2.19.so (path inode=1970324837263076)
bash     43 root  mem       REG    0,0                   288364 /lib/x86_64-linux-gnu/libnss_compat-2.19.so (path inode=1970324837262956)
bash     43 root  mem       REG    0,0                   288510 /lib/x86_64-linux-gnu/libc-2.19.so (path inode=1970324837263102)
bash     43 root  mem       REG    0,0                   288373 /lib/x86_64-linux-gnu/libdl-2.19.so (path inode=1688849860552309)
bash     43 root  mem       REG    0,0                   288352 /lib/x86_64-linux-gnu/libtinfo.so.5.9 (path inode=1970324837262944)
bash     43 root  mem       REG    0,0                   288312 /lib/x86_64-linux-gnu/ld-2.19.so (path inode=2251799813973560)
bash     43 root  mem       REG    0,0                   328650 /usr/lib/locale/locale-archive (path inode=2814749767435210)
bash     43 root  mem       REG    0,0                   328744 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache (path inode=844424930460712)
bash     43 root    0u  unknown                                 /WINDOWS/console (stat: No such file or directory)
bash     43 root    1u  unknown                                 /WINDOWS/console (stat: No such file or directory)
bash     43 root    2u  unknown                                 /WINDOWS/console (stat: No such file or directory)
bash     43 root  255u  unknown                                 /WINDOWS/console (stat: No such file or directory)
root@localhost:~#

/WINDOWS/console辺りにハックの痕跡が見て取れます。

なんとなく/sysを覗いてみた

/sys/devices/virtual/net/eth0/addressで本当のMacアドレスが見えました。

root@localhost:/tmp# cat /sys/devices/virtual/net/eth0/address
08:00:27:d3:5c:6e

なんとなくls三兄弟

lsmod、lspci、lsusb全部ダメでございました。

root@localhost:~# lsmod
libkmod: ERROR ../libkmod/libkmod-module.c:1619 kmod_module_new_from_loaded: could not open /proc/modules: No such file or directory
Error: could not get list of modules: No such file or directory

root@localhost:~# lspci
pcilib: Cannot open /proc/bus/pci
lspci: Cannot find any working access method.

root@localhost:~# lsusb
unable to initialize libusb: -99
root@localhost:~#

なんとなくuptime

/proc/loadavgがなくて怒られました。/proc/uptimeは読めてるのでかなり惜しい。

root@localhost:~# uptime
Error: /proc must be mounted
  To mount /proc at boot you need an /etc/fstab line like:
      proc   /proc   proc    defaults
  In the meantime, run "mount proc /proc -t proc"
root@localhost:~#

なんとなくuname

root@localhost:~# uname -a
Linux localhost 3.4.0+ #1 PREEMPT Thu Aug 1 17:06:05 CST 2013 x86_64 x86_64 x86_64 GNU/Linux
root@localhost:~#

まとめ

現状はカーネルにお願いする機能の多くが使用不能っぽいです。
LXCのコンテナの中相当と考えるとそんなに違和感の無い結果かと思いました。

夏の正式リリースまでに色々面白いことが出来る様になるといいですね。

sshごしにgoogle-drive-ocamlfuseのOAuth認証を行う方法

はじめに

ファイルサーバにGoogle Driveをマウントして、重要なファイルをバックアップする仕組みを作ろうとしています。

Google Driveのマウントにはgoogle-drive-ocamlfuseを使うことにしたのですが、このソフトはアカウント認証(OAuth)の際にGUIなブラウザを要求してきます。

うちのファイルサーバにはXが無いのでブラウザは表示不可です。
X転送するにしても認証のためだけにブラウザ(と大量のX関係の依存ライブラリ)をインストールするのは超イマイチ。

google-drive-ocamlfuseはヘッドレスモードが想定されていますが、新たにGoogle Appの登録をしないといけない?などで面倒っぽいです。
(ドキュメントにも「ピンチの時だけ使え」って書いてますし。)

などなどの制約を鑑みて、今回はちょっとしたハックでこの状況を切り抜けることにしました。

手順

設定者はMacWindowsからsshを用いてファイルサーバにログインしている想定です。

カレントディレクトリにfirefoxという名前のシェルスクリプトを作る。

google-drive-ocamlfuseはOAuth認証を行う際に、ブラウザとしてxdg-open、firefoxgoogle-chromeの順に実行ファイルを探します。

つまり、これらと同名のシェルスクリプトを用意すれば、google-drive-ocamlfuseのOAuthの認証シーケンスに介入することが出来ます。

今回は"firefox"と言うシェルスクリプトを作って、まんまとgoogle-drive-ocamlfuseを化かしてやろうと思います。

./firefox

#! /bin/sh

echo $* > /dev/stderr

このスクリプトが呼ばれる際、stdoutはどっかにリダイレクトされてて端末にメッセージが出せないので、stderrに出力する様にします。
パーミッションを付けるのをお忘れなく。

chmod 777 firefox

OAuth認証を行う。

さっき作った偽firefoxのいるディレクトリにパスを通しつつ、google-drive-ocamlfuseを起動してOAuth認証を開始します。

firefoxのおかげで、ブラウザが呼び出されるタイミングでhttps://accounts.google.comで始まる URLが表示されるはずです。

$ PATH=`pwd`:$PATH google-drive-ocamlfuse
/bin/sh: 1: xdg-open: not found
https://accounts.google.com/o/oauth2/auth?client_id=564921029129.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fgd-ocaml-auth.appspot.com%2Foauth2callback&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&response_type=code&access_type=offline&approval_prompt=force&state=ystNgUZ5iSKxd%2FlP7WQ4jolWLy5QbZyrTXXXXXXXX

この端末は閉じないでこのまま置いといてください。

手元のブラウザで認証を行う。

お手元の超リッチなクライアントPCで動くブラウザのアドレスバーに先ほどのアドレスを貼り付けて認証を行います。

f:id:moguno:20160324004444p:plain

認証後にこの画面に遷移したらOKです。

f:id:moguno:20160324004505p:plain

1分ほど待ってgoogle-drive-ocamlfuseを起動した端末に下記のメッセージが表示されればOAuth認証は成功です。

Access token retrieved correctly.

原理

(カミングスーン)