tmuxでコンソール共有が便利すぎる
「ふええプログラミング分からない><」とか「ふええコンパイルうまくいかない><」とか、
場合によっては環境に依存しそうな問題を友人から持ちかけられたことって多いとおもいます。
というかぼくは持ちかける側なのですが(´・ω・`)
普通は「いまPATHは〜で、これを実行するとこういう結果がでて...」みたいにSkypeでログを切り貼りしながら話を進めたりするんですが、これ結構心が折れる。「ここがおかしい」「ここってどこ!!」「(スクリーンショットを貼る)」みたいなこともよくあるし。
で、えりっくさんなりの解決策が1つ見つかったのでご紹介。
tmuxを使うことで、相談してきた相手の見ているコンソールをまんま自分の目の前に再現し、さらにそのまま相手の権限で操作を行うことができます(ちょっと危険)。
ちなみに学校やVPSのように外部からSSHアクセスできる環境が条件となります(ローカルのひとごめんね!)。
相談する側の操作:
tmux -S /tmp/shared_sock
chmod 777 /tmp/shared_sock
でtmux起動、ソケット作成。このソケットファイルは互いにアクセスできる場所に置きましょう。
相談を受ける側の操作:
tmux -S /tmp/shared_sock attach
だけ。
これで全く同じ画面を共有できます。
カーソルは当然ながら共通なので、Skype音声通話で「ちょっと操作していい?」みたいに同期をとりながらやるとストレスなく操作ができていいかんじです。
ちなみにMacだと「システム環境設定」から「リモートログイン」でsshdを立てられます。ローカルですごい数の相談相手にお願いする場合とかに便利かも?
注意:exitで終了すると両方のセッションが落ちてしまうので、相談を受けた側はtmux detachで退席しましょう!!!
screenでもできることはわかっていたんですが、tmuxのほうがこんなにお手軽だったので。
http://sourceforge.jp/magazine/06/09/11/088249
参考までにscreenでの実現方法も書いておきます。
追記:
http://partty.org/ 使おう
第7回カーネル/VM探検隊で仮想マシン作った発表してきました
題名のとおりです、カーネル/VM探検隊でLTしてきました!
カーネル/VM探検隊に関しては↓
http://atnd.org/event/kernelvmseven
https://sites.google.com/site/kernelvm/
えーと、数日間でMIPS R3000アーキテクチャの仮想マシンをErlang(!)で途中まで書きました。
recrioって名前を付けました。一応動いてはいますが、割り込みあたりがまだちゃんと実装できてなかったり、
ELFロードできてなかったり、なんかもういろいろダメですね...
スライドはこちら。
http://www.slideshare.net/siritori/ss-12638392
リポジトリはこちら。
https://github.com/siritori/recrio
recrio_debugモジュールでなんかいろいろテストして遊べます。
3> recrio_debug:test(). true addi reg(2) := reg(0) + <<255,0>> reg2 : 00000000000000001111111100000000 0 : 00100000000000101111111100000000 4 : 00100000000000011111011110001111 8 : 00100100001000011111000011111111 C : 00000000000000010000100001000010 10 : 00010000001000000000000000000100 14 : 10101100010000010000000000000000 18 : 00100000010000100000000000000100 1C : 00001000000000000000000000000011 20 : 00000000000000000011111111001101 addi reg(1) := reg(0) + <<247,143>> reg1 : 00000000000000001111011110001111 reg2 : 00000000000000001111111100000000 0 : 00100000000000101111111100000000 4 : 00100000000000011111011110001111 8 : 00100100001000011111000011111111 C : 00000000000000010000100001000010 10 : 00010000001000000000000000000100 14 : 10101100010000010000000000000000 18 : 00100000010000100000000000000100 1C : 00001000000000000000000000000011 20 : 00000000000000000011111111001101 4>
MIPSアーキテクチャのいいお勉強になりますね。実際、だんだんオペコードを覚えてきました...
バイナリパターンマッチのお陰でデコード部分がすんごい簡単に書けるのがステキだなって思いました。
ErlangなくせにOTPも使ってませんごめんなさい
詳しいことはスライドを見て下さいね!゜+.(・ω・)゜+.゜
Twitterにおけるつぶやきの即時話題推定技術「どたばたかいぎ」の裏側(実装途中)
OverView
最初はPerlで書いてたんですけど、今は主にErlangで書いてあります。TwitterのUser Streamsからつぶやきを取得し、MeCabの形態素解析にかけて名詞のみ抽出しています。MeCabは既に強化済です*1。
このエントリのお話すること
Erlang内でつかっているもの
べ、べつに http://naoyat.hatenablog.jp/entry/2012/01/04/220639 のエントリの存在に書き終えたあとで気づいたりとかしてないし...車輪の再発明じゃないし...(´;ω;`)
1.ErlangからOauthライブラリ使ってUserStreamsにつなぐところ
何度見たかわからないid:takkkunのhttp://d.hatena.ne.jp/takkkun/20091016/1255722692を読みながらhttp://d.hatena.ne.jp/polistes/20111130/1322663545とうまいことつなげる。
つぶやきが流れてきたらjiffyちゃんでdecodeしたのちにコールバック関数CallBack(Bin, Args)でゴニョゴニョできるような設計に。なにか画面出力するときはNotifierに流しこむようにしておきました。じゃないと標準出力が非常に残念なことになる(´・ω・`) 流れてきた欠片を拾うだけのstreamer/2と、それを受け取ってからプロセス生成したりNotifierに伝えるlistenerがあります。要erlang-oauth, jiffy。get_access_token()という関数があるんだけどコピペなので省略。
-module(userstream). -author("Eric Sartre <siritori@gmail.com>"). -export([start/5, stop/1]). -define(CONSUMER_KEY, "ConsumerKey"). -define(CONSUMER_SECRET, "ConsmerSecret"). start(AccessToken, AccessTokenSecret, Notifier, CallBack, Args) -> Listener = spawn(?MODULE, listener, [Notifier, CallBack, Args]), Streamer = spawn(fun() -> Consumer = {?CONSUMER_KEY, ?CONSUMER_SECRET, hmac_sha1}, Options = [{sync, false}, {stream, self}], URL = "https://userstream.twitter.com/2/user.json", case oauth:post(URL, [], Consumer, AccessToken, AccessTokenSecret, Options) of {ok, RequestId} -> streamer(RequestId, Listener); {error, Reason} -> send(Listener, {error, Reason}) end end), {ok, Streamer}. stop(Streamer) -> send(Streamer, stop), receive {Streamer, stopped} -> stopped end. streamer(RequestId, Listener) -> receive {http, {RequestId, stream_start, _Headers}} -> send(Listener, started), streamer(RequestId, Listener); {http, {RequestId, stream, Part}} -> case Part of <<"\r\n">> -> noop; _ -> send(Listener, {stream, Part}) end, streamer(RequestId, Listener); {http, {RequestId, {error, Reason}}} -> send(Listener, {error, Reason}), erlang:exit(stream_disconnected); {From, stop} -> httpc:cancel_request(RequestId), send(Listener, stop), send(From, stopped) end. listener(Notifier, CallBack, Args) -> receive {_Streamer, start} -> send(Notifier, start), listener(Notifier, CallBack, Args); {_Streamer, {stream, Part}} -> spawn(fun() -> {Data} = jiffy:decode(Part), case lists:keyfind(<<"text">>, 1, Data) of false -> ok; {<<"text">>, Text} -> CallBack(unicode:characters_to_binary(Text), Args) end end), listener(Notifier, CallBack, Args); {_Streamer, {error, Reason}} -> send(Notifier, {error, Reason}); {_Streamer, stop} -> send(Notifier, stop) end. send(To, Msg) -> To ! {self(), Msg}.
たとえばこんなふうにつかう。
-module(hoge). -compile(export_all). callback(Bin, _Args) -> printer ! {tweet, Bin}. test() -> erlang:register(printer, spawn(?MODULE, printer, [])), userstream:start("なんたら", "かんたら", printer, fun ?MODULE:callback/2, []). printer() -> receive {_Listener, start} -> io:format("Info: stream started~n"), printer(); {tweet, Bin} -> io:format("tweet!:~ts~n", [Bin]), printer(); {_Listener, {error, Reason}} -> io:format("Error: ~p~n", [Reason]); {_Listener, stop} -> io:format("Info: stream stopped~n") end.
たぶん一行づつUserStreamが流れるとおもう。
2.どたばたかいぎのCore部分
どたばたかいぎではさっきのuserstreamモジュールをこんなふうに使っています。category.etsには単語のカテゴリのリスト、redirect.etsには単語の言い換えのリスト(ほぼ要素数は1)が格納されてます。
-module(dotabata). -export([kaigi/0, stop/1, callback/2, printer/0]). kaigi() -> {ok, _} = mecab:init_context(), {ok, CategoryTab} = ets:file2tab("category.ets"), {ok, RedirectTab} = ets:file2tab("redirect.ets"), Tab = {CategoryTab, RedirectTab}, {ok, AccessToken, AccessTokenSecret} = userstream:get_access_token(), register(printer, spawn(fun ?MODULE:printer/0)), Streamer = userstream:start(AccessToken, AccessTokenSecret, printer, fun ?MODULE:callback/2, Tab), {Streamer, CategoryTab, RedirectTab}. stop({Streamer, CategoryTab, RedirectTab}) -> userstream:stop(Streamer), ets:delete(CategoryTab), ets:delete(RedirectTab). printer() -> receive {_Listener, start} -> io:format("Info: stream started~n"), printer(); {tweet, Bin, Tokens} -> io:format("tweet!:~ts~n", [Bin]), lists:foreach(fun(I) -> io:format("~ts~n", [I]) end, Tokens), io:format("~n"), printer(); {_Listener, {error, Reason}} -> io:format("Error: ~p~n", [Reason]); {_Listener, stop} -> io:format("Info: stream stopped~n") end. callback(Bin, {CategoryTab, RedirectTab}) -> {ok, Tokens0} = mecab:parse(Bin), Tokens = lists:foldl(fun(I, Acc) -> case ets:lookup(RedirectTab, I) of [] -> [I|Acc]; [{I, Token}] -> Token ++ Acc end end, [], Tokens0), Categories = lists:foldl(fun(I, Acc) -> case ets:lookup(CategoryTab, I) of [] -> [I|Acc]; [{I, Category}] -> [I|Category] ++ Acc end end, [], Tokens), printer ! {tweet, Bin, sets:to_list(sets:from_list(Categories))}.
キモはcallback/2。mecabモジュール(後述)によってつぶやきから名詞のリストを取り出し、redirect.etsによって表記ゆれを吸収しています。その後category.etsによってその上位概念を取得し、すべてリストに追加してuniqueにしたあとprinterに投げて表示させています。
3.ErlangからMeCabを触るNIFインターフェイス
Erlangで形態素解析をするためにMeCabさんを使います。NIFをつかってErlangVMにドゴォォォンと載せちゃう。まずは.erlのスケルトン。
-module(mecab). -export([load/0, init_context/0, parse/1, destroy_context/0]). load() -> erlang:load_nif("./mecab", 0). init_context() -> {error, library_not_loaded}. parse(Bin) when is_binary(Bin) -> {error, library_not_loaded}. destroy_context() -> {error, library_not_loaded}.
んでもってCをゴリゴリ書く。大枠はこんなかんじ。こう書くとErlangからはfunc0/0とfunc1/3が見えるようになる。
#include "erl_nif.h" static ERL_NIF_TERM func0_(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ・ ・ } static ERL_NIF_TERM func1_(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ・ ・ } static ErlNifFunc nif_funcs[] = { {"func0", 0, func0_}, {"func1", 3, func1_}, }; ERL_NIF_INIT(mecab, nif_funcs, NULL, NULL, NULL, NULL)
引数でbinaryを指定して受け取って、それを文字列にするあたりのコード。
enif_inspect_binaryでERL_NIF_TERMなbinaryをErlNifBinaryに変換するんですって。ErlNifBinaryは使った後に後片付けが必要。
static ERL_NIF_TERM parse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; enif_inspect_binary(env, argv[0], &bin); char *input = (char*)malloc(bin.size+1); memcpy(input, bin.data, bin.size); input[bin.size] = '\0'; enif_release_binary(&bin);
逆に文字列('\0'で終わってないけど)からbinaryに変換するコード。ERL_NIF_TERMになったのでもうこいつはVMの管理下にあるのでreleaseはしない。
ErlNifBinary bin; enif_alloc_binary(node->length, &bin); memcpy(bin.data, node->surface, node->length); ERL_NIF_TERM bin = enif_make_binary(env, &bin);
というわけで全コード。
#include "erl_nif.h" #include <stdio.h> #include <stdlib.h> #include <mecab.h> #include <string.h> static mecab_t *mecab = NULL; static ERL_NIF_TERM tuple2(ErlNifEnv *env, const char *s1, const char *s2) { ERL_NIF_TERM t1 = enif_make_atom(env, s1); ERL_NIF_TERM t2 = enif_make_atom(env, s2); return enif_make_tuple2(env, t1, t2); } static ERL_NIF_TERM init_context(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { if(mecab != NULL) return tuple2(env, "error", "already_initialized"); if((mecab = mecab_new(0, NULL)) == NULL) { return tuple2(env, "error", "failed_to_initialize"); } return tuple2(env, "ok", "initialized"); } static ERL_NIF_TERM destroy_context(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { if(mecab != NULL) { mecab_destroy(mecab); mecab = NULL; } return tuple2(env, "ok", "destroyed"); } static ERL_NIF_TERM trace_node_(ErlNifEnv *env, mecab_node_t *node, ERL_NIF_TERM rest) { if(node == NULL) return rest; if( strstr(node->feature, "代名詞")) return trace_node_(env, node->next, rest); if(!strstr(node->feature, "名詞,")) return trace_node_(env, node->next, rest); if( strstr(node->feature, "接尾")) return trace_node_(env, node->next, rest); if( strstr(node->feature, "非自立")) return trace_node_(env, node->next, rest); ErlNifBinary bin; enif_alloc_binary(node->length, &bin); memcpy(bin.data, node->surface, node->length); ERL_NIF_TERM tail = enif_make_list_cell(env, enif_make_binary(env, &bin), rest); return trace_node_(env, node->next, tail); } static ERL_NIF_TERM trace_node(ErlNifEnv *env, mecab_node_t *node) { return trace_node_(env, node, enif_make_list(env, 0)); } static ERL_NIF_TERM parse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { if(mecab == NULL) { return tuple2(env, "error", "context_not_initialized"); } /* map ErlNifBinary to char string */ ErlNifBinary bin; enif_inspect_binary(env, argv[0], &bin); char *input = (char*)malloc(bin.size+1); memcpy(input, bin.data, bin.size); input[bin.size] = '\0'; enif_release_binary(&bin); /* parse to node*/ const mecab_node_t *node = mecab_sparse_tonode(mecab, input); if(node == NULL) return tuple2(env, "error", "failed_to_parse"); ERL_NIF_TERM ok = enif_make_atom(env, "ok"); return enif_make_tuple2(env, ok, trace_node(env, node)); } static ErlNifFunc nif_funcs[] = { {"init_context", 0, init_context}, {"destroy_context", 0, destroy_context}, {"parse", 1, parse} }; ERL_NIF_INIT(mecab, nif_funcs, NULL, NULL, NULL, NULL)
trace_node_で末尾再帰しながらMeCabのnodeリストをErlangのバイナリのリストに変換していってます。ついでに名詞の振り分けとかもここでやっちゃってる。
コンパイルで大コケする。
[eric@TSUBAKI]% gcc -I$ERL_ROOT/usr/include `mecab-config --cflags` `mecab-config --libs` --undefined suppress -flat_namespace -fPIC -shared -o mecab.so mecab.c
$ERL_ROOTはえりっくさんの環境では/opt/local/lib/erlang/でした。ちなみに便宜上環境変数で表現しただけでこういう環境変数がなにかのお陰でセットされたりすることはありません。
こうやって使う↓
1> l(mecab). {module,mecab} 2> mecab:load(). ok 3> mecab:init_context(). {ok,initialized} 4> String = unicode:characters_to_binary("Erlang触って睡眠不足いえーい。"). <<69,114,108,97,110,103,232,167,166,227,129,163,227,129, 166,231,157,161,231,156,160,228,184,141,232,182,179,227, 129,...>> 5> {ok, L} = mecab:parse(String). {ok,[<<231,157,161,231,156,160,228,184,141,232,182,179>>, <<"Erlang">>]} 6> lists:foreach(fun(I)->io:format("~ts~n", [I]) end, L). 睡眠不足 Erlang ok 7>
ツッコミ歓迎
「お前ここ遅くなるぞ」とかいろいろあったら教えて下さい。
リアルタイムにTwitterのつぶやきの話題推定をする技術「どたばたかいぎ」研究途中報告
お久しぶりです。えりっくです。実装に関しては別エントリにまとめることにします。
筑波大学大学院システム情報工学研究科産学間連携推進室にて、ぼく含め3人で研究をしています。ここでの研究は企業と連携をとり、社会に還元することを目的としています。もし実用化できれば、Twitterユーザたちにサービスとして展開することも考えています。 既にこの研究は既にニコニコ大百科(有限会社未来検索ブラジル様)、Pixiv百科事典(Pixiv様)の記事データ提供によるご協力を頂いております。
で、どういう技術なの。
タイトルの通りつぶやきからその話題を推定する技術の研究をしています。
この研究がうまくいくと、TwitterのTLに張り付く必要がなくなります。
とあなたがつぶやいたら、
「Wordの出来の悪さに比べてヤツの出来はやばい。Microsoft本気出してる。」
「PerlよりRubyにしませんか(´・ω:;.:... 」
みたいなつぶやきがだれかさんによってTLに流れた時に勝手にあなたに通知されるようになります。
映画サマーウォーズの1シーンにもあるように、TLのつぶやきが話題ごとにまとめられて表示されるユーザインタフェースのTwitterクライアントもできるかもしれません。夢がひろがるね。
アイディア
一般的に、普通はtf-idf(単語が出てきた回数)だとか使ってその語彙分布から文章の話題を推定します。ところがTwitterの文章は140文字以内なのでこういうアプローチが使えない。じゃあどうするか。
つぶやきに含まれる特徴的な語の上位概念・関連概念を予め用意しておき、つぶやきに含まれる単語1つ1つの上位概念・関連概念を探索して取得する
っていうのをおもいつきました。例えば「Erlang」という単語には「関数型言語」「オープンソース」「並行計算」「Erlang」「プログラミング言語」が対応するように辞書を用意しておけば、「Erlang」を含むつぶやきの話題は「関数型言語」「オープンソース」「並行計算」「Erlang」「プログラミング言語」である、と推定ができます(いろいろ端折った)。っていう。仕組み自体は至極簡単でしょ。「おもいついた」っていうのが恥ずかしくなるくらい。
理想と現実
「上位概念なんてどっから持ってくるんだよ」
うん、言うと思った。でもこれみんなよく知ってるアレを使うんですよ。
Wikipedia
ニコニコ大百科
Wikipedia
「関連項目」だとか「カテゴリ」あたりから上位概念とか関連概念を引っ張り出してきます。あと記事名も取得して持っておきます。これを文章中から特徴語を抽出するために使います。
WikipediaはMySQLのダンプをPerlのようなもので殴ってデータ生成
ニコニコ大百科はデータ提供してもらって自前パースしてPerlのようなものd(ry
Pixivもデータ提供してもらってPerlの(ry
快く承諾していただいたブラジル様とPixiv様に感謝。
頑張ったお陰でいいかんじの概念データベースが出来上がりました。例えば
というつぶやきからは
- ももいろクローバー
- スターダストプロモーション
- 1994年生
- ライブアイドル
- 日本の歌手
- 日本の俳優
- アイドルに関するスタブ
- 浜松市出身の人物
- 皮膚科学
- 顔
- えくぼ
- 笑い
- 存命人物
- 日本のアイドルグループ
- 百田夏菜子
- 日本のアイドル
- ももいろクローバーZ
が取得できました。
GRUB rescueで九死に一生を得た had a narrow escape from death thanks for GRUB rescue
Debianを手が滑っていれてしまった。いろいろカスタマイズして遊んでた。
パーティションいじってるときにどうやら失敗したようで起動時にこれが出た。
GRUB Loading.
Welcome to GRUB!error: no such partition.
Entering rescue mode...
grub rescue>
へー・・・。
grub rescue>helpUnknown command 'help'
grub rescue>h
Unknown command 'h'
grub rescue>?
Unknown command '?'
grub rescue>ls
(hd0) (hd0,msdos6) (hd0,msdos5) (hd0,msdos1)
grub rescue>echo 'fu*k'
Unknown command 'echo'
f*ck!!!!!!!!
ここで@_ITF_から
insmod (h0,?)/boot/grub/normal.mod
normal
してみろって言われる。
grub rescue>insmod (h0,msdos6)/boot/grub/normal.mod
error: no such fileなんとかかんとか
grub rescue>
oh. しばらく遊ぶ。
grub rescue>ls (hd0,msdos1)/
error: unknown file system
grub rescue>ls (hd0,msdos6)/
bin boot dev etc home initrd.img lib lost+found media mnt opt proc root sbin selinux srv sys tmp usr var vmlinuz
grub rescue>ls (hd0,msdos6)/boot/grub
915resolution.mod acpi.mod affs.mod afs.mod afs_be.mod aout.mod at_keyboard.mod ata.mod ata_pthru.mod befs.mod befs_be.mod biosdisk.mod bitmap.mod bitmap_scale.mod blocklist.mod boot.img boot.mod bsd.mod bufio.mod cat.mod cdboot.img chain.mod cmostest.mod cmp.mod command.lst configfile.mod core.img cpio.mod cpuid.mod crc.mod crypto.lst crypto.mod cs5536.mod date.mod datehook.mod datetime.mod device.map diskboot.img dm_nv.mod drivemap.mod echo.mod efiemu.mod efiemu32.o efiemu64.o elf.mod example_functional_test.mod ext2.mod extcmd.mod fat.mod font.mod fs.lst fshelp.mod functional_test.mod gcry_arcfour.mod gcry_blowfish.mod gcry_camellia.mod gcry_cast5.mod gcry_crc.mod gcry_des.mod gcry_md4.mod gcry_md5.mod gcry_rfc2268.mod gcry_rijndael.mod gcry_rmd160.mod gcry_seed.mod gcry_serpent.mod gcry_sha1.mod gcry_sha256.mod gcry_sha512.mod gcry_tiger.mod gcry_twofish.mod gcry_whirlpool.mod gettext.mod gfxmenu.mod gfxterm.mod gptsync.mod grldr.img grub.cfg grubenv gzio.mod halt.mod handler.lst hashsum.mod hdparm.mod hello.mod help.mod hexdump.mod hfs.mod hfsplus.mod iorw.mod iso9660.mod jfs.mod jpeg.mod kernel.img keystatus.mod linux.mod linux16.mod lnxboot.img loadenv.mod locale loopback.mod ls.mod lsmmap.mod lspci.mod lvm.mod mdraid.mod memdisk.mod memrw.mod minicmd.mod minix.mod mmap.mod moddep.lst msdospart.mod multiboot.mod multiboot2.mod nilfs2.mod normal.mod ntfs.mod ntfscomp.mod ohci.mod part_acorn.mod part_amiga.mod part_apple.mod part_bsd.mod part_gpt.mod part_msdos.mod part_sun.mod part_sunpc.mod partmap.lst parttool.lst parttool.mod password.mod password_pbkdf2.mod pbkdf2.mod pci.mod play.mod png.mod probe.mod pxe.mod pxeboot.img pxecmd.mod raid.mod raid5rec.mod raid6rec.mod read.mod reboot.mod regexp.mod reiserfs.mod relocator.mod scsi.mod search.mod search_fs_file.mod search_fs_uuid.mod search_label.mod serial.mod setjmp.mod setpci.mod sfs.mod sleep.mod tar.mod terminal.lst terminal.mod terminfo.mod test.mod tga.mod trig.mod true.mod udf.mod ufs1.mod ufs2.mod uhci.mod usb.mod usb_keyboard.mod usbms.mod usbtest.mod vbe.mod vbeinfo.mod vbetest.mod vga.mod vga_text.mod video.lst video.mod video_bochs.mod video_cirrus.mod video_fb.mod videotest.mod xfs.mod xnu.mod xnu_uuid.mod zfs.mod zfsinfo.mod
grub rescue>
どうやら今回ほしいものはmsdos6内にあるっぽい。
ここらへんで追加情報がくる。
grub rescue>set
prefix = (hd0,msdos7)/boot/grub
root = hd0,msdos6
grub rescue>set prefix=(h0,msdos6)/boot/grub
grub rescue>set root=h0,msdos6
grub rescue>insmod (h0,msdos6)/boot/grub/normal.mod
grub rescue>normal
やったあああああああ起動したああああああああああああああああああ
というわけでみなさん「normalなんてしらねーよ!」って言われたらこの環境変数を変えるように。あと英字配列にするように(この時点ではドライバが読まれてないので英字配列入力になってる)
で、普通ならこのあとちゃんとGRUB入れ直すんだけど。
なんか悔しかったのでもう一回ハマりにいった。
GRUB Loading.
Welcome to GRUB!error: no such partition.
Entering rescue mode...
grub rescue>set prefix=(h0,msdos6)/boot/grub
grub rescue>set root=h0,msdos6
grub rescue>insmod (h0,msdos6)/boot/grub/help.mod
grub rescue>help
(略)
grub rescue>insmod (h0,msdos6)/boot/grub/echo.mod
grub rescue>echo 'f*ck'
f*ck
grub rescue>insmod (h0,msdos6)/boot/grub/normal.mod
grub rescue>normal
(ドヤ顔
I installed Debian because of some mistake. customized various settings.
Because I tweaked some partitions, the computer failed to boot and showed me this:
error: no such partition
grub rescue>
Erlang sshモジュールで遊ぼうとした tried to play by Erlang ssh module
最初はこのモジュール簡単に使えるんじゃないかなーとか思ってたんだけどそげぶされた。。。
リファレンス読んでこんなふうにリモートにつなごうとしたんだけど標準入力がブロッキングされて詰んだ
1>application:start(crypto).
ok
2>application:start(ssh).
ok
3>{ok, Ref} = ssh:connect("example.com", 22, [{user, "user"}, {password, "passwd"}]).
New host example.com accept [y/n]?
あわわわ。Erlang Question ML探してこんなのみつけた
http://erlang.2086793.n4.nabble.com/SSH-client-example-td2106867.html
あとこのコードも参考にした
https://github.com/jj1bdx/sshrpc/blob/master/src/client_test_nonotp.erl
読んでからいざリベンジ。
1>application:start(crypto).
ok
2>application:start(ssh).
ok
3>ssh:shell("example.com", [{user, "user"}, {password, "passwd"}, {silently_accept_hosts, true}]).
>ls
Desktop
Documents
Downloads
Library
Maildir
Movies
Music
Pictures
Public
.
.
.
ははぁ、リモートマシンにつなぐときは{silently_accept_hosts, true}でやるとブロッキングされずにできるみたい。
結局ssh_channel:send/2使ってリモートマシンと通信はできなかったけど近いうちにやる。
以下英文
At first, I thought I could use this module easily. But the expectation was broken.
First of all, I read user reference page and tried to connect to remote host by as follows, but standard input was strangely blocked:
1>application:start(crypto).
ok
2>application:start(ssh).
ok
3>{ok, Ref} = ssh:connect("example.com", 22, [{user, "user"}, {password, "passwd"}]).
New host example.com accept [y/n]?
Oops. I searched in Erlang Question ML so that I found this page:
http://erlang.2086793.n4.nabble.com/SSH-client-example-td2106867.html
And, I also referred this code:
https://github.com/jj1bdx/sshrpc/blob/master/src/client_test_nonotp.erl
After reading two codes, I revenged to use ssh.
1>application:start(crypto).
ok
2>application:start(ssh).
ok
3>ssh:shell("example.com", [{user, "user"}, {password, "passwd"}, {silently_accept_hosts, true}]).
>ls
Desktop
Documents
Downloads
Library
Maildir
Movies
Music
Pictures
Public
.
.
.
Hah, when we connect some hosts, we can connect with adding option{silently_accept_hosts, true} so that standard input isn't blocked.
After all, I couldn't communicate with remote machine using ssh_channel:send/2. I'll try one of these days.