Powered By Blogger

2014年6月30日月曜日

MacからSakura VPSをセットアップ

備忘録.
さくらVPSはデフォルトでrootログインだったりで色々不安なので変更が必要。
下の元ネタを参考にさせて頂きました。
元ネタ1
元ネタ2

1. MacでRSA暗号鍵の生成
Macで鍵のペアを生成する
$ cd .ssh/
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/***/.ssh/id_rsa): id_rsa_sakura
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in id_rsa_sakura.
Your public key has been saved in id_rsa_sakura.pub.
The key fingerprint is:
........
The key's randomart image is:
+--[ RSA 2048]----+
|     .           |
..........
+-----------------+

2. ユーザー作成
ターミナルを起動してsshでサーバにログイン
ssh root@[IPアドレス] -p 22
ログイン用のユーザー(名前は自由)を作成。
# useradd [USER名] -G wheel
# passed [USER名]

3. yumのアップデート
なぜか初期状態ではyumがupdateしてくれないので、
# vi /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/os/$basearch/
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4
priority=1
protect=1
以下、各リポジトリでmirrorlistをコメントアウトし、理研のサイトをbaseurlに記述。
# yum clean all
# sudo yum update

4. sudoの設定
root権限を使えるwheelグループについて設定
sudo vi /etc/pam.d/su
でファイルを開いて以下の行のコメントアウトを外す。
# auth required pam_wheel.so use_uid
sudo vi /etc/login.defs に以下の行を追加
SU_WHEEL_ONLY yes
sudo visudoで以下の行のコメントアウトを外す
# %wheel ALL=(ALL) ALL

セキュリティを強化するためにSSHのポート番号とrootでのログインを禁止。(sshd再起動後反映)
sudo vi /etc/ssh/sshd_config で以下のように修正
Port [任意のport no]
PermitRootLogin no
PasswordAuthentication no

5. scpで公開鍵の送信
Mac側からscp接続をして生成した公開鍵を送る
$ scp id_rsa_[VPS名].pub root@[IPアドレス]:/home/[USER名]/.ssh/authorized_keys

サーバに公開鍵を送信したら、authorized_keysの所有者とパーミッションを変更してサーバ側のsshdを再起動
$ ssh root@[IPアドレス] -p 22
# su - USER_NAME
# sudo chown [USER名]:[USER名] .ssh/authorized_keys
# chmod 600 /home/[USER名]/.ssh/authorized_keys
# exit #<= rootに戻る
# /etc/init.d/sshd restart
# exit

6. Mac側で簡単にログイン出来るようにSSHのconfigに設定しておく
Mac側で .ssh の config に、以下を追加しておく。
Host sakura
 User [ユーザー名]
 Port [上で設定したSSHのポート]
 Hostname [さくらのIP]
 IdentityFile ~/.ssh/id_rsa_sakura
 TCPKeepAlive yes
 IdentitiesOnly yes

2014年6月15日日曜日

BloggerにTeXの数式を貼る

以前から使ってたやつが色々使いにくいので、MathJaxを試してみる。
元ネタ
テスト: $e^{i\pi}=-1$
んー…iPhoneではSafariもChromeも変換しないな。
PuffinならiPhoneでも表示される。
数式はMathJaxを使うことが一般的らしいのだが

2013年5月3日金曜日

REPLのラッパー

備忘録

Guile(schemeの処理系)のインタープリタも↑↓のコマンド履歴とか対応してなくて使いにくい。
履歴遡ろうと↑とか押しても

> guile

scheme@(guile-user)> ^[[A^[[A^[[1;2D

みたいな事になる。

rlwrapを使えばOK。
インストールはubuntuではaptitudeで出来た。
windowsのcygwinでもsetupでrlwrapで検索しインストール出来る。
インストールの詳細は省く。簡単に分かるはず。

使い方は簡単
起動したいインタープリタのコマンドの前にrlwrapを付けるだけ。

> rlwrap guile

2012年6月15日金曜日

Mac: Clojureコンソール(clj)を使いやすくする

Clojureはコンソールからcljで起動出来る。

$ clj
Clojure 1.4.0
user=>

これが↑↓キーで入力履歴が出なかったりしてイマイチ使いづらい。
Clojureのビルドツールleiningenを使って起動すると↑↓キーで入力履歴が出る様になる。
ちょっとClosureを試してみるだけなのでビルドツールは要らないと思っていたが、
入力履歴が使えないのは不便なのでleiningenを使ってcljを起動してみると
入力履歴が使える様になった。
因みにClojureもleiningenもhomebrewからインストール出来る。

$ lein repl
REPL started; server listening on localhost port
user=> 

2012年6月4日月曜日

ペアノ算術とProlog

ペアノ算術をPrologで表現してみる。

元ネタ
第3巻『数学ガール/ゲーデルの不完全性定理』
Prolog by Example: Peano Arithmetics

Swi-Prologを使います。

と…その前にペアノの公理で自然数を定義しよう。

ペアノの公理1
0は自然数である



Prologコード
natural_n(0).

ペアノの公理2
どんな自然数nに対しても後続数s(n)は自然数である



Prologコード
natural_n(s(N)) :- natural_n(N).

ペアノの公理3
どんな自然数nに対してもs(n)は0ではない



Prologコードは無し

ペアノの公理4
どんな自然数m,nに対しても、s(m)=s(n)ならばm=nである



Prologコードは無し
ペアノの公理5
自然数nに対する述語P(n)で、次の2つが成り立つとする。
・P(0)である。
・どんな自然数kに対しても、P(k)ならばP(s(k))である。
このときどんな自然数nに対してもP(n)が成り立つ。



Prologコードは無し
ここまでのPrologコードまとめ
natural_n(0).
natural_n(s(N)) :- natural_n(N).

実行してみる。
?- natural_n(X).
X = 0 ;
X = s(0) ;
X = s(s(0)) ;
X = s(s(s(0))) ;
X = s(s(s(s(0)))) ;
X = s(s(s(s(s(0))))) .

自然数が出来た!
「これが自然数?」と言いたい人もいるでしょうが、これで良いんです!!
s(0)を1
s(s(0))を2
s(s(s(0)))を3
というふうに読み替えて下さい。


さて、ここからがペアノ算術

足し算の公理1
どんな自然数nに対しても、n + 0 = nが成り立つ


Prologコード
sum(N,0,N).

余談ですが自然数に0を含める考え方(0,1,2 ...)と含めない考え方(1,2,3 ...)があり、上の足し算の公理は前者です。
後者の場合の公理はこうなります。
足し算の公理1(0は自然数に含めない)
どんな自然数nに対しても、n + 1 = s(n)が成り立つ


"0"という自然数は存在しないので、こうするしかないのでしょう。
この場合は、
s(1)を2
s(s(1))を3
s(s(s(1)))を4
というふうに読み替えて下さい。

Prologコード
sum(N,1,s(N)).

足し算の公理2



Prologコード
sum(N,s(M),s(K)) :- sum(N,M,K).

Prologコードまとめ
sum(N,0,N).     %In case of natural numbers contain 0.
sum(N,1,s(N)).  %In case of natural numbers contain NO 0.
sum(N,s(M),s(K)) :- sum(N,M,K).  %K=N+M

X=3+2を実行してみます。

?- sum(s(s(s(0))),s(s(0)),X).
X = s(s(s(s(s(0))))) ;
false.

X=5になりました。
おっと、ここで作った自然数は"5"とは言わないんでしたね。
s(s(s(s(s(0)))))ですね、でも長ったらしいので5と言う事にします。

因みに、0は自然数に含めない場合で
X=4+3を実行してみます。

?- sum(s(s(s(1))),s(s(1)),X).
X = s(s(s(s(s(s(1)))))) ;
false.

X=7になりました。

0を自然数に含める場合は、例えば2をs(s(0))と表現すると
sum(N,s(M),s(K)) :- sum(N,M,K).
を再帰的に評価し、最終的に
sum(N,0,N).
にマッチして、再帰の階段を戻って結果が出る訳です。

0を自然数に含めない場合は、例えば2をs(1)と表現して、最終的に
sum(N,1,s(N)).
の方にマッチするのです。

ではここからは掛け算です。
掛け算の公理1
0を自然数に含める場合

Prologコード
prod(M,0,0).

0を自然数に含めない場合

Prologコード
prod(M,1,M).

掛け算の公理2



Prologコード
prod(M,s(N),P) :-
     prod(M,N,K),
     sum(K,M,P).   % K=M+N

Prologコードまとめ
prod(M,0,0).    %In case of natural numbers contain 0.
prod(M,1,M).    %In case of natural numbers contain NO 0.
prod(M,s(N),P) :-
    prod(M,N,K),
    sum(K,M,P).   % K=M+N

実行

0を自然数に含める場合、X=2*3

?- prod(s(s(0)),s(s(s(0))),X).
X = s(s(s(s(s(s(0)))))) ;
false.

X=6となりました。


0を自然数に含めない場合、X=2*4

?- prod(s(1),s(s(s(1))),X).
X = s(s(s(s(s(s(s(1))))))) ;
false.

X=8となりました。

2012年4月21日土曜日

Blocks関連のバグがデバッグコンパイルで再現しないケース

TOMOHISAさんのブログ記事
BLOCKSを使った記述で、リリースビルドのみにクラッシュする事例
これは元のコードの問題はスタック領域上のブロックオブジェクトをスコープ外で使ってしまったという割と有りがちなバグだったのですが、 念のため検証してみました。

ところがブロックオブジェクトのデフォルトの生成場所(スタック領域かヒープ領域か)がデバッグコンパイル時にはどうも違うらしくて、 そういう挙動を知らずにデバッグコンパイルで検証してしまった為にハマってしまいました。

今回のはちゃんとリリースコンパイルでもテストしないといけないという教訓です。

ブロックのデフォルトの生成場所はスタック領域なのですが、デバッグだろうがリリースだろうがそれは同じだと思い込んでいました。

特に__block属性付き変数をキャプチャするとブロックの生成場所は最初からヒープになるみたいです。何でかな?…

検証コード
コードはTOMOHISAさんのものですが、
NSLog(〜〜,block) の箇所とコメントは私が検証の為に追加しました。
因みに_tweetはこのコードが属するオブジェクトのメンバ関数です。
ARCです。
//
    NSMutableArray *arrRows = [NSMutableArray arrayWithCapacity:0];
    { //検証コード1
#warning this code only crash on Release Build.... Don't use this
        NSMutableDictionary * dicRow = [NSMutableDictionary dictionaryWithCapacity:0];
        [dicRow setValue:NSLocalizedString(@"Pattern 1 Crash",nil) forKey:kDicKeyLinkPopCellText];
        [arrRows addObject:dicRow];
        dispatch_block_t block = ^{
            
            NSString *str = [NSString stringWithFormat:@"%@",[_tweet valueForKey:@"text"]];
            
            [[UIPasteboard generalPasteboard] setString:str];
            [[JTCAppNotificationManager sharedManger] startTimerNotificationWithMessage:NSLocalizedString(@"Copy succeeded", @"Copy succeeded") dulation:2.5 iconName:@"w17-check.png"];

        };
        NSLog(@"Pattern 1 %@",block);
        [dicRow setValue:block forKey:kDicKeyLinkPopBlock];
    }
    { //検証コード2
        NSMutableDictionary * dicRow = [NSMutableDictionary dictionaryWithCapacity:0];
        [dicRow setValue:NSLocalizedString(@"Pattern 2 __block",nil) forKey:kDicKeyLinkPopCellText];
        [arrRows addObject:dicRow];
#warning this code is not the way recommended how to use __block ... not recommended
        __block id bt = _tweet;
        dispatch_block_t block = ^{
            
            NSString *str = [NSString stringWithFormat:@"%@",[bt valueForKey:@"text"]];
            
            [[UIPasteboard generalPasteboard] setString:str];

            [[JTCAppNotificationManager sharedManger] startTimerNotificationWithMessage:NSLocalizedString(@"Copy succeeded", @"Copy succeeded") dulation:2.5 iconName:@"w17-check.png"];
            
        };
        NSLog(@"Pattern 2 %@",block);
        [dicRow setValue:block forKey:kDicKeyLinkPopBlock];
    }
    { //検証コード3
        NSMutableDictionary * dicRow = [NSMutableDictionary dictionaryWithCapacity:0];
        [dicRow setValue:NSLocalizedString(@"Pattern 3 only declare bt crash",nil) forKey:kDicKeyLinkPopCellText];
        [arrRows addObject:dicRow];
#warning this code only crash on Release Build.... Don't use this
        id bt = _tweet;
        dispatch_block_t block = ^{
            
            NSString *str = [NSString stringWithFormat:@"%@",[bt valueForKey:@"text"]];
            
            [[UIPasteboard generalPasteboard] setString:str];
            
            [[JTCAppNotificationManager sharedManger] startTimerNotificationWithMessage:NSLocalizedString(@"Copy succeeded", @"Copy succeeded") dulation:2.5 iconName:@"w17-check.png"];
        };
        NSLog(@"Pattern 3 %@",block);
        [dicRow setValue:block forKey:kDicKeyLinkPopBlock];
    }
    { //検証コード4
        NSMutableDictionary * dicRow = [NSMutableDictionary dictionaryWithCapacity:0];
        [dicRow setValue:NSLocalizedString(@"USE THIS:Pattern 4 declare bt and copy block",nil) forKey:kDicKeyLinkPopCellText];
        [arrRows addObject:dicRow];
        id bt = _tweet;
        dispatch_block_t block = ^{
            
            NSString *str = [NSString stringWithFormat:@"%@",[bt valueForKey:@"text"]];
            
            [[UIPasteboard generalPasteboard] setString:str];
            
            [[JTCAppNotificationManager sharedManger] startTimerNotificationWithMessage:NSLocalizedString(@"Copy succeeded", @"Copy succeeded") dulation:2.5 iconName:@"w17-check.png"];
        };
        NSLog(@"Pattern 4 %@",block);
        [dicRow setValue:[block copy] forKey:kDicKeyLinkPopBlock];
    }
    
    NSMutableArray *sections = [NSMutableArray arrayWithObject:arrRows];
    TOVLinkPopoverViewController *controller= [[TOVLinkPopoverViewController alloc] init];
    controller.arrayLink = sections;




デバッグビルドでのログ出力

2012-04-21 13:49:22.109 TOVPopoverSample[10592:707] Pattern 1 <__NSMallocBlock__: 0xfe44ee0>
2012-04-21 13:49:34.734 TOVPopoverSample[10592:707] Pattern 2 <__NSMallocBlock__: 0xfe45b20>
2012-04-21 13:49:39.624 TOVPopoverSample[10592:707] Pattern 3 <__NSMallocBlock__: 0x13dc50>
2012-04-21 13:49:43.224 TOVPopoverSample[10592:707] Pattern 4 <__NSMallocBlock__: 0xfe45110>

見ての通り4パターンともmallocされたブロック、つまりヒープ上に生成されてます。 これではバグの検証は出来ませんね。
別に全部問題ないじゃん、みたいに見えてしまいます。
「ほらスタック領域にブロック生成されるからヒープにコピーしないと」と言う結論を期待したのに「なんで…」と数時間悩んでしまいました。


リリースビルドでのログ出力

2012-04-21 13:10:39.912 TOVPopoverSample[10504:707] Pattern 1 <__NSStackBlock__: 0x2fe54510>
2012-04-21 13:10:54.860 TOVPopoverSample[10504:707] Pattern 2 <__NSMallocBlock__: 0x149250>
2012-04-21 13:11:18.754 TOVPopoverSample[10504:707] Pattern 3 <__NSStackBlock__: 0x2fe544c4>
2012-04-21 13:12:11.226 TOVPopoverSample[10504:707] Pattern 4 <__NSStackBlock__: 0x2fe544ac>

ほぼ予想通りStackBlockとなってます。
このスタックブロックを辞書に登録しておいてスコープ外で使おうとしているのでバグだね、と分かる訳です。
ただパターン2、__block属性の変数をキャプチャしたケースだけはMallocBlockとなってます。
なぜこのケースではヒープに生成されるのか理由は分かりませんが、この為に問題無いかの様に動いたのですね。


結論
Blocksはデバッグビルドでのテストだけで満足してはならない。
リリースビルドでも入念にテストすべきである。


因みに。。。
このケースでは正解は4なのですが、いつもコピーする方が良い訳ではないので注意が必要です。
ヒープにコピーしたらしたで、リークだとか別の心配をしないといけなくなりますから。
4ではブロックをスコープ外で使いたい為にヒープにコピーしています。
ただし!!
ヒープにコピーしたブロックを使い終わったら忘れない様にリリースしないといけません。
今回のはARCなので問題なさそうではありますが。

__blockをキャプチャするとヒープブロックになるのを知ってたのなら2も正解じゃん、
という意見もあるかも知れませんが、そういう裏ワザ的なのはここでは不正解とさせて頂きます(笑)