エンジニアになりたい

エンジニアです

NetworkManagerをコマンドラインから利用する

何も考えずにゆるふわでGUIを使っていたが、急に何も返事しなくなった。

コマンドラインからNetworkManagerを使うにはnmcliコマンドを使う。

詳しくはあまり調べていない。使い方だけ。

いつもお世話になっている安心と信頼のArchWikiに書いてあった。

$ sudo nmcli dev wifi connect <ssid> password <password>

元々 ssidname だったが分かりやすく変えてある。

Linuxでtmuxのコピー結果をクリップボードにコピーする

いろんな記事を探していたがどうしても出来なかったので共有する。

とは言っても、すごく単純な問題だったような気がする。どうしても出来ない!って人の助けになればと思う。

結論から言うと、以下を .tmux.conf に記述すると出来る。tmuxのキーバインドはデフォルトのままである。

unbind -t emacs-copy M-w
unbind -t emacs-copy C-w
bind-key -t emacs-copy M-w copy-pipe "xsel -bi"
bind-key -t emacs-copy C-w copy-pipe "xsel -bi"

説明

ubind

unbind コマンドで emacs-copy コマンドに割当られているキーバインドを解除している。

bind-key

今度は逆に bind-key コマンドで キーバインドemacs-copy コマンドに割り当てている。

copy-pipe

copy-pipe コマンドはコピーモード中にセレクションをコピーして、次のコマンドに渡す。コピーモードでコピーした結果を xsel -lib に渡してクリップボードにコピーしている。tmux1.8以上から出来るようになった。

XSel

xselコマンドラインからXセレクションを操作するツールである。Xセレクションとはいわゆるクリップボードの機能のことであり、PRIMARY、SECONDARY、CLIPBOARDの3種類がある。

PRIMARYは選択した時にその部分が格納されるバッファで、CLIPBOARDはコピーした時に格納されるバッファらしい。SECONDARYは一般的なアプリケーションでは使われないようである。-b オプションでクリップボードセレクションを使うようにし、-i オプションで標準入力をセレクションに読ませる。

xselはtmuxと別途インストールする必要がある。

今まで出来なかったと思われる理由

.tmux.confの設定が反映されていなかった

今思うと古いtmuxのプロセスが残っているせいで設定が反映されていない可能性があった。tmuxのプロセスを殺して起動し直すと良い。

$ ps aux | grep tmux
$ kill "ID"

unbindしていなかった

いろんな記事でcopy-pipeを使う方法は書いてあった。しかし私の場合はその前にコピーコマンドをunbindする必要があった。

KeySnailのキーバインドがGitHubのショートカットとコンフリクトする問題

私はEmacsユーザであり、エディタはもちろんブラウザでもEmacsキーバインドを使えたら便利だと考えている。それを叶えてくれるものがKeySnailである。

github.com

一方で私は普段GitHubをよく利用する。GitHubは独自のキーボードショートカットを用意していて、とても便利に使えるらしい。しかし、私のようにブラウザ上のあらゆるページでEmacsキーバインドを使いたい人からするとかなり邪魔である。

この問題を解消する方法は簡単で、KKKというプラグインをインストールすれば良い。

これがKKKのアイコンらしい。

https://github.com/mooz/keysnail/raw/master/plugins/icon/kkk.icon.png

KKKは特定のサイトのkeydown及びkeyupイベントを殺してくれる。これを使えばGitHub上のショートカットを殺せる。使い方は簡単である。以下の設定を.keysnail.jsのPRESERVEエリアへ張り付ければ良い。

plugins.options["kkk.sites"] = ["^https?://([0-9a-zA-Z]+\\.)?github\\.com/"];

ちなみに、言うまでもないかもしれないがプラグインは以下の場所からインストール出来る。

github.com

同じ悩みを持つ人がこの記事を見て解決してくれれば幸いである。

RustでFizzBuzz

プログラミング言語Rustと、そのパッケージマネージャであるCargoを使ってFizzBuzzを書いていく。

要件は以下の通り。

1. 3の倍数の数字の時はfizzを出力
2. 5の倍数の数字の時はbuzzを出力
3. 3と5の倍数の数字の時はfizzbuzzを出力
4. それ以外の数字の時はそのまま数字を出力

雛形を作って実行

以下のように雛形を作る。

$ cargo new RustFizzBuzz --bin

Cargoを使って以下のように実行出来る。

$ cd RustFizzBuzz
$ cargo run
Hello, world!

これはsrcディレクトリ下のmain.rsが実行されることで表示されてる。

テストを書く

ルート下にtestsディレクトリを作って以下の内容のtest_rust_fizzbuzz.rsを設置する。Cargoはtestsという名前のディレクトリを見て、そこにあるテストファイルを実行してくれる。

extern crate RustFizzBuzz;
use RustFizzBuzz::rust_fizzbuzz;

#[test]
fn _1is_1() {
    assert_eq!("1", rust_fizzbuzz::fizzbuzz(1));
}

これはRustFizzBuzzクレイトをリンクして、その中のrust_fizzbuzzモジュールを使用するという意味である。最初に雛形を作る時点でRustFizzBuzzクレイトは作られている。

モジュールrust_fizzbuzzを定義するために、src下に以下の内容のlib.rsファイルを作成する。

pub mod rust_fizzbuzz;

このように宣言するとCargoはsrcディレクトリ下のrust_fizzbuzz.rsファイルを見つけてモジュール化してくれる。

それではsrc下に以下のような内容のrust_fizzbuzz.rsファイルを作成する。

pub fn fizzbuzz(n: i32) -> String{
    return n.to_string();
}

この時点でディレクトリ構造は以下のようになっているはず。

├── Cargo.lock
├── Cargo.toml
├── src
│   ├── lib.rs
│   ├── main.rs
│   └── rust_fizzbuzz.rs
└── tests
    └── test_rust_fizzbuzz.rs

ここまで書けばテストが実行出来るはずなので、以下のようにして実行する。

$ cargo test
tests is correct? [n,y,a,e]: n
   Compiling RustFizzBuzz v0.1.0 (file:///home/pro/RustProjects/RustFizzBuzz)
     Running target/debug/test_rust_fizzbuzz-50ecfb7694c5c790

running 1 test
test can_test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

実装

以下のように実装を行った。

pub fn fizzbuzz(n: i32) -> String{
    match n {
        n if n % 5 == 0 && n % 3 == 0 => "fizzbuzz".to_string(),
        n if n % 5 == 0 => "buzz".to_string(),
        n if n % 3 == 0 => "fizz".to_string(),
        _ => n.to_string()
    }
}

テストコードは以下のようになった。

extern crate RustFizzBuzz;
use RustFizzBuzz::rust_fizzbuzz;
#[test]
fn can_test() {
    assert_eq!(1, 1);
}
#[test]
fn _1is_1() {
    assert_eq!("1", rust_fizzbuzz::fizzbuzz(1));
}
#[test]
fn _3is_fizz() {
    assert_eq!("fizz", rust_fizzbuzz::fizzbuzz(3));
}
#[test]
fn _5is_buzz() {
    assert_eq!("buzz", rust_fizzbuzz::fizzbuzz(5));
}
#[test]
fn _15is_fizzbuzz() {
    assert_eq!("fizzbuzz", rust_fizzbuzz::fizzbuzz(15));
}

このままだと実装が微妙なのでリファクタリングを行って以下のようになった。

pub fn fizzbuzz(n: i32) -> String {
    match (n % 3, n % 5) {
        (0, 0) => "fizzbuzz".to_string(),
        (_, 0) => "buzz".to_string(),
        (0, _) => "fizz".to_string(),
        _ => n.to_string()
    }
}

テストも全部通ったので大丈夫そう。

まとめ

プロジェクトを作るところから、テストを書いて、モジュールとして実装、リファクタリングまでを行った。Cargo1つで何でも出来るという感じで、とても楽だった。

今回書いたものは全てGitHub上においてある。もうちょっと改良している。

github.com

Goddard Streamingを使用する方法

Goddard Streamingを使用する

Goddard Streamingとは

Goddard StreamingはNS-2シミュレータで使われるストリーミングシステム(クライアントとサーバ)である。

Streaming Media System for NS-2: http://ns-2.blogspot.jp/2007/05/streaming-media-system-for-ns-2.html

Goddard Streamingをダウンロードする

以下からGoddard Streamingの最新版をダウンロードする。

http://perform.wpi.edu/downloads/goddard/goddard-ns.tgz

Goddard Streamingをインストールする

Goddard Streamingをインストールする手順を以下に示す。

※NS-2は~/ns2/ns-allinone-2.35という構成になっていることとする。

  1. ダウンロードしたファイルを展開する。 展開するとgoddard-nsというディレクトリが作成され、その中にREADMEgoddard.tarINSTALLが入っている。
  2. さらにgoddard.tarを展開する。 展開するとgoddardtclというディレクトリが作成される。
  3. 作成されたディレクトリやファイルを移動する。
    以下のコマンドを実行して移動させる。
$ cp -r goddard-ns/goddard ~/ns2//ns-allinone-2.35/ns-2.35/

 

$ cp -r goddard-ns/tcl/goddard ~/ns2/ns-allinone-2.35/ns-2.35/tcl/

 
4. アプリケーションクラスに2つのpublic methodsを追加する。

  • ~/ns2/ns-allinone-2.35/ns-2.35/apps/app.hの54行目当たりに以下のように追加する。

追加前

class Application : public Process {
public:
        Application();
        virtual void send(int nbytes);
        virtual void recv(int nbytes);
        virtual void resume();

追加後

public:
        Application();
        virtual void send(int nbytes);
        virtual void recv(int nbytes);
        virtual void resume();

        /* For Goddard Streaming Application */
        inline virtual void send(int nbytes, AppData* data) { send(nbytes); }
        inline Agent* get_agent() { return agent_; }

 
5. ~/ns2/ns-allinone-2.35/ns-2.35/tcl/lib/ns-lib.tclに、source ns-default.tclの前の285行目当たりに以下を追加する。

追加前

# MPLS
source ../mpls/ns-mpls-simulator.tcl
source ../mpls/ns-mpls-node.tcl
source ../mpls/ns-mpls-ldpagent.tcl
source ../mpls/ns-mpls-classifier.tcl

source ns-default.tcl

追加後

# MPLS
source ../mpls/ns-mpls-simulator.tcl
source ../mpls/ns-mpls-node.tcl
source ../mpls/ns-mpls-ldpagent.tcl
source ../mpls/ns-mpls-classifier.tcl

# Goddard Streaming Application
source ../goddard/goddard-class.tcl
source ../goddard/goddard-default.tcl

source ns-default.tcl

 
6. ~/ns2/ns-allinone-2.35/ns-2.35/Makefile.inに以下を記述する。

  • OBJ_CCリストの336行目当たりに以下を追加する。

追加前

xcp/xcpq.o xcp/xcp.o xcp/xcp-end-sys.o \
wpan/p802_15_4csmaca.o wpan/p802_15_4fail.o \
wpan/p802_15_4hlist.o wpan/p802_15_4mac.o \
wpan/p802_15_4nam.o wpan/p802_15_4phy.o \
wpan/p802_15_4sscs.o wpan/p802_15_4timer.o \
wpan/p802_15_4trace.o wpan/p802_15_4transac.o \
apps/pbc.o \
@V_STLOBJ@

追加後

xcp/xcpq.o xcp/xcp.o xcp/xcp-end-sys.o \
wpan/p802_15_4csmaca.o wpan/p802_15_4fail.o \
wpan/p802_15_4hlist.o wpan/p802_15_4mac.o \
wpan/p802_15_4nam.o wpan/p802_15_4phy.o \
wpan/p802_15_4sscs.o wpan/p802_15_4timer.o \
wpan/p802_15_4trace.o wpan/p802_15_4transac.o \
apps/pbc.o \
goddard/udpapp.o goddard/mchannel_proc.o \
goddard/gframe_queue.o goddard/goddard.o goddard/gplayer.o \
@V_STLOBJ@
  • NS_TCL_LIBリストの529行目当たりに以下を追加する。

追加前

tcl/mpls/ns-mpls-node.tcl \
tcl/mpls/ns-mpls-simulator.tcl \
tcl/lib/ns-pushback.tcl \
tcl/lib/ns-srcrt.tcl \
tcl/mcast/ns-lms.tcl \
tcl/lib/ns-qsnode.tcl \
@V_NS_TCL_LIB_STL@

追加後

tcl/mpls/ns-mpls-node.tcl \
tcl/mpls/ns-mpls-simulator.tcl \
tcl/lib/ns-pushback.tcl \
tcl/lib/ns-srcrt.tcl \
tcl/mcast/ns-lms.tcl \
tcl/lib/ns-qsnode.tcl \
tcl/goddard/goddard-class.tcl \
tcl/goddard/goddard-default.tcl \
@V_NS_TCL_LIB_STL@

 
7. Makefileを作成してmakeする。(なぜかこの後の7、8の手順をやらずに出来てしまった。10を参照)

以下を実行すると出来るとGoddard StreamingのINSTALLには書いてあったが私は出来なかった。

$ ~/ns2/ns-allinone-2.35/ns-2.35/configure
$ ~/ns2/ns-allinone-2.35/ns-2.35/make

※私の環境ではMakefile:93: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.と出てmake出来なかったので、Makefileを開き、すべての空白8つをtabに置換した。しかし結局この方法では出来ないので意味はない。
 
8. NS-2自体をビルドする。

~/ns2/ns-allinone-2.35/ns-2.35/下のMakefileを作成してmakeしたところでGoddard Streamingがインストールされることはなかった。

少し力技ではあるが、NS-2自体を再度ビルドしてしまうことにする。

また、再度ビルドしようとするとnsやらnamという実行ファイルのシンボリックリンクを作成しようとするのであるが、すでにファイルがある場合はシンボリックリンクを作成しないので、~/ns2/ns-allinone-2.35/installln -sとなっているところをすべてln -sfとしてしまう。

さらに、nsと打って実行される、実行ファイルである/usr/local/bin/nsへのシンボリックリンクも621行目辺りの

ln -sf $CUR_PATH/ns-$NSVER/ns${EXE} ns${EXE}

の次に

ln -sf ns${EXE} /usr/local/bin/ns

と書いて張ってしまう。

その後は以下のようにする。

$ cd `~/ns2/ns-allinone-2.35`
$ sudo ./install

 
9. exampleファイルを実行してテストする。

以下のようにして、実行できるかテストする。

$ cd `~/ns2/ns-allinone-2.35/ns-2.35/tcl/goddard/ex/`
$ ns test-goddard.tcl

実行して、xgraphのウィンドウが表示されれば成功である。

f:id:pro_shunsuke:20141015200232p:plain

 
10. Makefileを作成してmakeする

7、8のやり方でなくても出来た。出来た要因は定かではないが記述する。

/usr/local/bin/nsシンボリックリンクを張る。

$ ln -sf ~/ns2/ns-allinone-2.35/ns-2.35/ns /usr/local/bin/ns

その後以下のようにしてmakeする

$ cd ~/ns2/ns-allinone-2.35/ns-2.35/
$ sudo ./configure
$ sudo make all

あとは9を実行してテストする。

8の方法だと、NS-2を最初からビルドするので時間がかかる。こちらのやり方を推奨する。

NS2を使用する方法

NS-2を使用する

NS-2とは

インターネット上のネットワーク通信は実際に環境を構築して実験を行うことが望ましいが、膨大なコストや時間がかかってしまい現実的とは言えない。そこでネットワークシミュレータを使用し、実験を行うことが一般的である。NS-2は数あるネットワークシミュレータの中で最も広く普及しているものの1つである。

The Network Simulator - ns-2: http://www.isi.edu/nsnam/ns/

NS-2をビルドする

NS-2のダウンロード

以下より最新版をダウンロードする

http://sourceforge.net/projects/nsnam/

現在(2014年10月9日)の段階ではver.2.35が最新である。バージョンによって多少動作が異なる可能性がある。

任意の場所に置く。ここでは~/ns2に置くこととする。

NS-2のビルド

NS-2をビルドする手順を以下に示す。

  1. 圧縮ファイルを展開するとns-allinone-2.35というディレクトリが作成される。
  2. ~/ns2/ns-allinone-2.35に移動し、./installを実行して、NS-2をコンパイルする。 Ns-allinoneパッケージが以下の場所にインストールされる。
    • tcl8.5.10: ~/ns2/ns-allinone-2.35/{bin,include,lib}
    • tk8.5.10: ~/ns2/ns-allinone-2.35/{bin,include,lib}
    • otcl: ~/ns2/ns-allinone-2.35/otcl-1.14
    • tclcl: ~/ns2/ns-allinone-2.35/tclcl-1.20
    • ns: ~/ns2/ns-allinone-2.35/ns-2.35/ns
    • nam: ~/ns2/ns-allinone-2.35/nam-1.15/nam
    • xgraph: ~/ns2/ns-allinone-2.35/xgraph-12.2
    • gt-itm: ~/ns2/ns-allinone-2.35/itm
  3. パスを追加する

bashを使っている場合は以下を~/.bashrcに記述する。

export NS_HOME="~/ns2/ns-allinone-2.35"
PATH=$PATH:$NS_HOME/bin:$NS_HOME/tcl8.5.10/unix
export PATH=$PATH:$NS_HOME/tk8.5.10/unix
export LD_LIBRARY_PATH=$NS_HOME/otcl-1.14:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$NS_HOME/lib:$LD_LIBRARY_PATH
export TCL_LIBRARY=$NS_HOME/tcl8.5.10/library

追加した後、source ./bashrcを実行する。
4. ns-2.35ディレクトに移動し、./validateを実行し、NS-2が利用できることを確認する。
5. ~/ns/ns-allinone-2.33/ns-2.33/tcl/exに移動し、ns simple.tclを実行する。nam画面が立ち上がれば成功。

f:id:pro_shunsuke:20141015192343p:plain

Vagrantで作った仮想環境上のサーバに他の端末からアクセスする

概要

Vagrantの仮想環境上に立てたサーバに、Androidなどの端末からアクセスする

やりかた

Vagrant

Vagrantのネットワーク機能には大きく分けて3つあり、目的によって使い分ける。

参考:Vagrantのネットワーク周りのあれこれ | Septeni Engineers' Blog | セプテーニ エンジニアブログ


種類 概要
プライベートネットワーク ホストOSとゲストOS間でのみ通信が行える
ポートフォワーディング ホストOSへの特定のポートを使った接続をゲストOSに転送する
パブリックネットワーク 同一ネットワーク内のどの端末からでもゲストOSと通信が行える


今回はポートフォワーディングを使ってホストOSの特定のポートへのアクセスをゲストOSへ転送する。

Vagrantfileのネットワークの設定をを以下のようにする。

config.vm.define :db1 do |db|
    db.vm.network :forwarded_port, guest: 80, host: 8080, :bridge => "en0: Wi-Fi (AirPort)"
end

ネットワークを forwarded_portにし、ゲストOSとホストOSのポートを指定、ネットワークインタフェースに bridge オプションを付けて、Wi-Fiネットワークからのアクセスを可能にする。

この状態で

$ vagrant up

を実行する。

既にupされていた場合は

$ vagrant reload

を実行する。

ローカル

無線LANIPアドレスを確認する。

$ ifconfig
wlan0     inetアドレス:192.168.0.2

これで、仮想環境上のサーバが動いていれば、同一のネットワークに繋いでいる端末で192.168.0.2:8080にアクセス出来るはず。

f:id:pro_shunsuke:20140922060714p:plain