bashの編集モードをviモードにしてみる [雑記]
普段Ubuntuで使ってるシェルはbashだ.
bashには編集モードというのがあって,デフォルトはemacsモードになっているらしいが,これをviモードに変更できる.普段使ってるエディタはVimなので,bashの編集モードもviモードにしたほうが便利だ.
というわけで変更してみる.
これでOK.実際は,.bashrcにでも書いておくといい.
ちなみにemacsモードにするにはviのところをemacsにすればいい.
これで,コマンドライン編集のときにviのキーバインドが(だいたい)使えるようだ.ま,Vimに慣れてる人なら違和感無く使えるというか,使いやすいと思う.
ところで,いろいろキーバインドを試していてビジュアルモードに入ろうとしたら,nanoが立ち上がってきた.どうやらnanoがデフォルト設定されているようだ.というわけでこれもVimに変更しておく.
この設定変更には,update-alternativesコマンドを使用するようだ.
まず,いまの設定を確認してみる.
すると,以下のような表示が出力されるはずだ.
これを見ると,確かにデフォルトはnanoになっているようだ.
で,Vimに変更するために,「3」を入力する.
変更されたかどうかは,再度同じコマンドを入力して,「3」のvim.basicが選択されていればOKだ.
これで完了.
bashには編集モードというのがあって,デフォルトはemacsモードになっているらしいが,これをviモードに変更できる.普段使ってるエディタはVimなので,bashの編集モードもviモードにしたほうが便利だ.
というわけで変更してみる.
set -o vi
これでOK.実際は,.bashrcにでも書いておくといい.
ちなみにemacsモードにするにはviのところをemacsにすればいい.
これで,コマンドライン編集のときにviのキーバインドが(だいたい)使えるようだ.ま,Vimに慣れてる人なら違和感無く使えるというか,使いやすいと思う.
ところで,いろいろキーバインドを試していてビジュアルモードに入ろうとしたら,nanoが立ち上がってきた.どうやらnanoがデフォルト設定されているようだ.というわけでこれもVimに変更しておく.
この設定変更には,update-alternativesコマンドを使用するようだ.
まず,いまの設定を確認してみる.
sudo update-alternatives --config editor
すると,以下のような表示が出力されるはずだ.
alternative editor (/usr/bin/editor を提供) には 4 個の選択肢があります。 選択肢 パス 優先度 状態 ------------------------------------------------------------ * 0 /bin/nano 40 自動モード 1 /bin/ed -100 手動モード 2 /bin/nano 40 手動モード 3 /usr/bin/vim.basic 30 手動モード 4 /usr/bin/vim.tiny 10 手動モード 現在の選択 [*] を保持するには Enter、さもなければ選択肢の番号のキーを押してください:
これを見ると,確かにデフォルトはnanoになっているようだ.
で,Vimに変更するために,「3」を入力する.
変更されたかどうかは,再度同じコマンドを入力して,「3」のvim.basicが選択されていればOKだ.
これで完了.
Google Testのアサーションをいろいろ使ってみる [Google Test]
前回に引き続き,Google Testを試してみる.
Google Testにはいろいろなアサーションが用意されてるので,それを試してみる.
前回と同様に適当なディレクトリにassert_projというディレクトリを作って,ファイル構成は以下のようにしてやる.なお,今回はアサーションのテストだけしかしないので,作成するファイルはCMakeLists.txtとassert_unittest.cppだけだ.
CMakeLists.txt
assert_unittest.cpp
じゃあビルド.前回と同様,assert_buildディレクトリを作ってビルド.
これで,assert_testバイナリが生成される.
実行は,
でOK.ARGS=-Vにすると詳細が表示されるんだけど,テストに失敗したときだけ詳細が表示されればいいんだったら,ARGS=--output-on-failureにするといい.ま,テスト成功のときはシンプルな表示で失敗のときにいろいろ表示されるほうが使いやすいかも.
アサーションの説明は,Google Test ドキュメント日本語訳の入門ガイドにあるアサーションあたりを読むと分かると思う.
ま,それだけだと寂しいので,テストの内容をいくつか,ざっくり書いとく.
TEST(TestAssert, Message)
アサーションに失敗したときにメッセージを出力するもの.flagがfalseのときに失敗して,「test failed at index 1」というメッセージが追加で表示される.成功のときはメッセージは表示されない.
TEST(TestAssert, Class)
値の比較をするアサーションは,組み込み型ならそのまま使える.もしユーザ定義型でも使いたい場合は,比較演算子を用意してやれば使える.今回の場合だと,EXPECT_EQとEXPECT_NEを使うので,==演算子と!=演算子を用意してやればよい.
TEST(TestAssert, CStr)
C言語文字列を比較したいときは,EXPECT_EQではなく,EXPECT_STREQを使う.EXPECT_EQだとポインタの比較になってしまい文字列そのものの比較にならない.
とりあえず今回はここまで.
お試しあれ.
Google Testにはいろいろなアサーションが用意されてるので,それを試してみる.
前回と同様に適当なディレクトリにassert_projというディレクトリを作って,ファイル構成は以下のようにしてやる.なお,今回はアサーションのテストだけしかしないので,作成するファイルはCMakeLists.txtとassert_unittest.cppだけだ.
assert_proj/ ├── CMakeLists.txt └── test └── assert_unittest.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 2.6) project(assert_test) enable_testing() find_package(Threads) set(CMAKE_INCLUDE_CURRENT_DIR ON) message(STATUS GTEST_DIR=$ENV{GTEST_DIR}) include_directories($ENV{GTEST_DIR}/include) link_directories($ENV{GTEST_DIR}/lib) add_executable(assert_test test/assert_unittest.cpp) target_link_libraries(assert_test gtest gtest_main) target_link_libraries(assert_test ${CMAKE_THREAD_LIBS_INIT}) add_test(NAME assert_test COMMAND assert_test)
assert_unittest.cpp
#include <gtest/gtest.h> // message output test TEST(TestAssert, Message) { bool flag[2] = {true, false}; for (int i = 0; i < 2; i++) { EXPECT_TRUE(flag[i]) << "test failed at index " << i; } } // bool test TEST(TestAssert, AssertTrue) { EXPECT_TRUE(true); ASSERT_TRUE(true); } TEST(TestAssert, AssertFalse) { EXPECT_FALSE(false); ASSERT_FALSE(false); } // value test TEST(TestAssert, Value) { int expected = 2; int actual = 2; EXPECT_EQ(expected, actual); // expected == actual int val1, val2; val1 = val2 = 3; EXPECT_NE(val1 , val2+1); // val1 != val2 EXPECT_LE(val1 , val2 ); // val1 <= val2 EXPECT_GE(val1 , val2 ); // val1 >= val2 EXPECT_LT(val1 , val2+1); // val1 < val2 EXPECT_LE(val1 , val2+1); // val1 <= val2 EXPECT_GT(val1+1, val2 ); // val1 > val2 EXPECT_GE(val1+1, val2 ); // val1 >= val2 } // class test class Point { private: int x_; int y_; public: Point(int x, int y) : x_(x), y_(y) {} bool operator==(const Point& obj) const { return (x_ == obj.x_) && (y_ == obj.y_); } bool operator!=(const Point& obj) const { return !(*this == obj); } }; TEST(TestAssert, Class) { Point a(0, 0); Point b(0, 1); EXPECT_EQ(a, a); EXPECT_NE(a, b); } // c string test TEST(TestAssert, CStr) { char str1[] = "aaa"; char str2[] = "aaa"; EXPECT_NE(str1, str2); EXPECT_STREQ(str1, str2); // "aaa" vs "aaa" strcpy(str2, "Aaa"); EXPECT_STRNE(str1, str2); // "aaa" vs "Aaa" EXPECT_STRCASEEQ(str1, str2); // "aaa" vs "Aaa" strcpy(str2, "bAA"); EXPECT_STRCASENE(str1, str2); // "aaa" vs "bAA" }
じゃあビルド.前回と同様,assert_buildディレクトリを作ってビルド.
mkdir assert_build cd assert_build/ cmake ../assert_proj/ make
これで,assert_testバイナリが生成される.
実行は,
make test ARGS=--output-on-failure
でOK.ARGS=-Vにすると詳細が表示されるんだけど,テストに失敗したときだけ詳細が表示されればいいんだったら,ARGS=--output-on-failureにするといい.ま,テスト成功のときはシンプルな表示で失敗のときにいろいろ表示されるほうが使いやすいかも.
アサーションの説明は,Google Test ドキュメント日本語訳の入門ガイドにあるアサーションあたりを読むと分かると思う.
ま,それだけだと寂しいので,テストの内容をいくつか,ざっくり書いとく.
TEST(TestAssert, Message)
アサーションに失敗したときにメッセージを出力するもの.flagがfalseのときに失敗して,「test failed at index 1」というメッセージが追加で表示される.成功のときはメッセージは表示されない.
TEST(TestAssert, Class)
値の比較をするアサーションは,組み込み型ならそのまま使える.もしユーザ定義型でも使いたい場合は,比較演算子を用意してやれば使える.今回の場合だと,EXPECT_EQとEXPECT_NEを使うので,==演算子と!=演算子を用意してやればよい.
TEST(TestAssert, CStr)
C言語文字列を比較したいときは,EXPECT_EQではなく,EXPECT_STREQを使う.EXPECT_EQだとポインタの比較になってしまい文字列そのものの比較にならない.
とりあえず今回はここまで.
お試しあれ.
簡単なコードでGoogle Testを使ってみる [Google Test]
前回,Google Testを使えるようにしたので,今回は,ごく簡単なコードに対してGoogle Testを使ってみることにする.
というわけで,Google Testの使い方について検索するとよく出てきて定番っぽい,2つの変数を加算するadd関数について試してみる.
なるべく,実際使う構成に近い方がイメージしやすいと思うので(といいつつも,単にadd関数だけなんて作ること無いと思うのだけど...)適当なディレクトリに,add_projというディレクトリを作ってやって,ファイル構成は以下のようにしてやる.あと,cmakeを使ってビルドしてみる.
それぞれのファイルの内容は以下のようになる.
CMakeLists.txt(CMake用の設定ファイル)
ちなみに,GTEST_DIRは,前回Google Testをダウンロード,展開したディレクトリだ.
うちの場合だと,~/googletest/gtest-1.6.0/になる.なので,
add.cpp(add関数の定義)
add.h(add関数の宣言)
main.cpp(add関数を使用するmainの定義)
test/add_unittest.cpp(add関数のテスト定義)
では,ビルドしてみる.
ビルドは,ソースファイルがあるディレクトリとは別のディレクトリにする(これをout-of-source buildとよぶらしい).同じディレクトリでもいいのだが,CMakeはかなり中間ファイルを生成してごちゃごちゃするので,別ディレクトリにするのがおすすめだ.
今回は,add_projと同一階層にadd_buildディレクトリを生成して,以下のようにしてやる.
で,これによって,2つのバイナリが生成される.
add_mainとaddだ.
add_mainのほうは,単にadd関数によって2と3を加算した結果を表示するだけのプログラムで,addのほうがadd関数のテストになる.今回は1+2の結果が3になることをテストしている.
テストの実行は,./addでもいいし,make testでもいい.
ただし,make testだと,結果は詳細は表示されない../addと同等の表示をしたければ,make test ARGS=-Vとしてやればいい.
なお,今回はadd_mainというadd関数を使ったプログラムも作ったが,単にadd関数のテストだけをやりたければ,main.cppはいらないし,add_mainの生成もしなくていい.
Google Testは,今回の値の一致テスト以外にもいろんなことができる.それについてはまた別の機会に...
では,お試しあれ.
というわけで,Google Testの使い方について検索するとよく出てきて定番っぽい,2つの変数を加算するadd関数について試してみる.
なるべく,実際使う構成に近い方がイメージしやすいと思うので(といいつつも,単にadd関数だけなんて作ること無いと思うのだけど...)適当なディレクトリに,add_projというディレクトリを作ってやって,ファイル構成は以下のようにしてやる.あと,cmakeを使ってビルドしてみる.
add_proj/ ├── CMakeLists.txt ├── add.cpp ├── add.h ├── main.cpp └── test └── add_unittest.cpp
それぞれのファイルの内容は以下のようになる.
CMakeLists.txt(CMake用の設定ファイル)
cmake_minimum_required(VERSION 2.6) project(add) enable_testing() find_package(Threads) set(CMAKE_INCLUDE_CURRENT_DIR ON) message(STATUS GTEST_DIR=$ENV{GTEST_DIR}) include_directories($ENV{GTEST_DIR}/include) link_directories($ENV{GTEST_DIR}/lib) add_executable(add_main main.cpp add.cpp) add_executable(add add.cpp test/add_unittest.cpp) target_link_libraries(add gtest gtest_main) target_link_libraries(add ${CMAKE_THREAD_LIBS_INIT}) add_test(NAME add COMMAND add)
ちなみに,GTEST_DIRは,前回Google Testをダウンロード,展開したディレクトリだ.
うちの場合だと,~/googletest/gtest-1.6.0/になる.なので,
としてやる.実際には,.bashrcにでも記載してやるといい.export GTEST_DIR=~/googletest/gtest-1.6.0
add.cpp(add関数の定義)
#include "add.h" int add(int x, int y) { return x + y; }
add.h(add関数の宣言)
#ifndef ADD_H #define ADD_H int add(int x, int y); #endif // ADD_H
main.cpp(add関数を使用するmainの定義)
#include <iostream> #include "add.h" int main() { int x = 2; int y = 3; std::cout << x << " + " << y << " = " << add(x, y) << std::endl; return 0; }
test/add_unittest.cpp(add関数のテスト定義)
#include <gtest/gtest.h> #include "add.h" TEST(TestAdd, add1) { ASSERT_EQ(3, add(1,2)); }
では,ビルドしてみる.
ビルドは,ソースファイルがあるディレクトリとは別のディレクトリにする(これをout-of-source buildとよぶらしい).同じディレクトリでもいいのだが,CMakeはかなり中間ファイルを生成してごちゃごちゃするので,別ディレクトリにするのがおすすめだ.
今回は,add_projと同一階層にadd_buildディレクトリを生成して,以下のようにしてやる.
mkdir add_build cd add_build/ cmake ../add_proj/ make
で,これによって,2つのバイナリが生成される.
add_mainとaddだ.
add_mainのほうは,単にadd関数によって2と3を加算した結果を表示するだけのプログラムで,addのほうがadd関数のテストになる.今回は1+2の結果が3になることをテストしている.
テストの実行は,./addでもいいし,make testでもいい.
ただし,make testだと,結果は詳細は表示されない../addと同等の表示をしたければ,make test ARGS=-Vとしてやればいい.
なお,今回はadd_mainというadd関数を使ったプログラムも作ったが,単にadd関数のテストだけをやりたければ,main.cppはいらないし,add_mainの生成もしなくていい.
Google Testは,今回の値の一致テスト以外にもいろんなことができる.それについてはまた別の機会に...
では,お試しあれ.
タグ:Google Test CMAKE
Google Testを使ってみる [Google Test]
C++のテストフレームワークとして,Google Testというのがあるので使ってみる.
Google Testはいろんなプラットフォームに対応しているらしい.例えばLinuxとかMac OS X,あとWindowsとかCygwinでも使えるらしい.
で,これをうちのビルドマシン上で使ってみる.ビルドマシンのOSはubuntu 12.04の64bit版だ.
では,まずは適当なディレクトリを作成し,Google Testをダウンロード,展開してやる.
そしたらライブラリを作成してやる.作成方法の詳細は展開先のREADMEに書かれてるので一度ざっと目を通しとくといいかも.あと,この作業でCMakeを使うので先にインストールしておく(使わなくてもできるけど).
というわけでCMakeのインストール
ライブラリ作成
これで,「libgtest.a」と「libgtest_main.a」が作成されるはずだ.実際テストするときはこのライブラリをリンクして使うことになる.
そしたら,試しにサンプルをビルドして,テストを実行してみる.
そうすると,以下の実行可能なファイルが作成されるはずだ.
試しにsample1_unittestを実行してみる.
そうするとテストが実行されて以下のような結果が表示されるはずだ.
実際には色もついて表示される.で,ここまで確認できればOK.
次のステップはサンプルじゃなくて自分のコードをテストすることになるのだが,それはまた次回.
Google Testはいろんなプラットフォームに対応しているらしい.例えばLinuxとかMac OS X,あとWindowsとかCygwinでも使えるらしい.
で,これをうちのビルドマシン上で使ってみる.ビルドマシンのOSはubuntu 12.04の64bit版だ.
では,まずは適当なディレクトリを作成し,Google Testをダウンロード,展開してやる.
cd ~/ mkdir googletest cd googletest/ wget http://googletest.googlecode.com/files/gtest-1.6.0.zip unzip gtest-1.6.0.zip
そしたらライブラリを作成してやる.作成方法の詳細は展開先のREADMEに書かれてるので一度ざっと目を通しとくといいかも.あと,この作業でCMakeを使うので先にインストールしておく(使わなくてもできるけど).
というわけでCMakeのインストール
sudo apt-get install cmake
ライブラリ作成
cd ~/googletest/gtest-1.6.0/ mkdir lib cd lib/ cmake ../ make
これで,「libgtest.a」と「libgtest_main.a」が作成されるはずだ.実際テストするときはこのライブラリをリンクして使うことになる.
そしたら,試しにサンプルをビルドして,テストを実行してみる.
cd ~/googletest/gtest-1.6.0/ mkdir build_sample cd build_sample/ cmake -Dgtest_build_samples=ON ../ make
そうすると,以下の実行可能なファイルが作成されるはずだ.
sample1_unittest sample2_unittest sample3_unittest sample4_unittest sample5_unittest sample6_unittest sample7_unittest sample8_unittest sample9_unittest sample10_unittest
試しにsample1_unittestを実行してみる.
./sample1_unittest
そうするとテストが実行されて以下のような結果が表示されるはずだ.
Running main() from gtest_main.cc [==========] Running 6 tests from 2 test cases. [----------] Global test environment set-up. [----------] 3 tests from FactorialTest [ RUN ] FactorialTest.Negative [ OK ] FactorialTest.Negative (0 ms) [ RUN ] FactorialTest.Zero [ OK ] FactorialTest.Zero (0 ms) [ RUN ] FactorialTest.Positive [ OK ] FactorialTest.Positive (0 ms) [----------] 3 tests from FactorialTest (1 ms total) [----------] 3 tests from IsPrimeTest [ RUN ] IsPrimeTest.Negative [ OK ] IsPrimeTest.Negative (0 ms) [ RUN ] IsPrimeTest.Trivial [ OK ] IsPrimeTest.Trivial (0 ms) [ RUN ] IsPrimeTest.Positive [ OK ] IsPrimeTest.Positive (0 ms) [----------] 3 tests from IsPrimeTest (0 ms total) [----------] Global test environment tear-down [==========] 6 tests from 2 test cases ran. (1 ms total) [ PASSED ] 6 tests.
実際には色もついて表示される.で,ここまで確認できればOK.
次のステップはサンプルじゃなくて自分のコードをテストすることになるのだが,それはまた次回.
タグ:Google Test CMAKE
NTPで時刻合わせをしてみる [雑記]
前回,ダイナミックDNSのIPアドレス更新を自動化したときに,ログを出力するようにした.で,このログには時刻も記録されるようにした訳だが,動作確認したときの時刻をよく見ると,ちょっと時刻がズレてることに気づいた.
そういえば,時刻合わせって,気にしてなかった...
というわけで,NTPで時刻合わせするようにしてみる.
NTPの詳細はリンク先を見てもらうとして,要は時刻合わせをするためのプロトコルだ.
で,その時刻合わせをするためにNTPクライアントをインストールしてやる.
そしたら,設定.
変更内容は,まず,既存のserverから始まる行をコメントアウトしてやる.うちの環境では16行目から始まる以下をコメントアウトした.
で,serverとして以下を追加した.
3つとも同じサーバ名にしているが,これでよい.実際には複数台のサーバがあって,別々のサーバにアクセスするようになっている.
これらのサーバは,日本標準時を供給している独立行政法人情報通信研究機構(NICT)によるサービスで提供されてるものだ.個人利用も許可されてるのでありがたく利用させてもらう.
で,設定が完了したら,NTPを再起動して設定を有効にしてやる.
そしたら動作チェック.
最初は以下のようにサーバ名の前は空白のはず.
で,しばらくするとNTPサーバ名の前に*か+がつくはずだ.ちなみに意味合いは,以下のようになっている.
これでOK.
あとは,dateコマンドで現在日時を表示できるのでちゃんと設定されてるかこれで確認できる.
これで時刻は正確に保たれるようになる.
そういえば,時刻合わせって,気にしてなかった...
というわけで,NTPで時刻合わせするようにしてみる.
NTPの詳細はリンク先を見てもらうとして,要は時刻合わせをするためのプロトコルだ.
で,その時刻合わせをするためにNTPクライアントをインストールしてやる.
sudo apt-get install ntp
そしたら,設定.
sudo vi /etc/ntp.conf
変更内容は,まず,既存のserverから始まる行をコメントアウトしてやる.うちの環境では16行目から始まる以下をコメントアウトした.
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board # on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for # more information. # server 0.ubuntu.pool.ntp.org # server 1.ubuntu.pool.ntp.org # server 2.ubuntu.pool.ntp.org # server 3.ubuntu.pool.ntp.org # Use Ubuntu's ntp server as a fallback. # server ntp.ubuntu.com
で,serverとして以下を追加した.
server ntp.nict.jp server ntp.nict.jp server ntp.nict.jp
3つとも同じサーバ名にしているが,これでよい.実際には複数台のサーバがあって,別々のサーバにアクセスするようになっている.
これらのサーバは,日本標準時を供給している独立行政法人情報通信研究機構(NICT)によるサービスで提供されてるものだ.個人利用も許可されてるのでありがたく利用させてもらう.
で,設定が完了したら,NTPを再起動して設定を有効にしてやる.
sudo /etc/init.d/ntp restart
そしたら動作チェック.
sudo ntpq -p
最初は以下のようにサーバ名の前は空白のはず.
remote refid st t when poll reach delay offset jitter ============================================================================== ntp-a3.nict.go. .NICT. 1 u 7 64 1 15.500 -2.257 0.000 ntp-b2.nict.go. .NICT. 1 u 6 64 1 17.769 -0.673 0.000 ntp-b3.nict.go. .NICT. 1 u 5 64 1 15.264 -0.223 0.000
で,しばらくするとNTPサーバ名の前に*か+がつくはずだ.ちなみに意味合いは,以下のようになっている.
"*" :現在,参照同期中のサーバー
"+" :現在,クロック誤り検査に合格したサーバー
"#" :現在,参照同期中ですが,距離が遠いサーバー
" " :現在,参照していないサーバー
"x" :現在,クロック誤り検査で不合格になったサーバー
"." :現在,参照リストからはずされたサーバー
remote refid st t when poll reach delay offset jitter ============================================================================== +ntp-a3.nict.go. .NICT. 1 u 19 64 177 5.291 2.974 4.926 +ntp-b2.nict.go. .NICT. 1 u 21 64 177 8.528 2.911 3.492 *ntp-b3.nict.go. .NICT. 1 u 23 64 177 9.097 2.497 2.848
これでOK.
あとは,dateコマンドで現在日時を表示できるのでちゃんと設定されてるかこれで確認できる.
これで時刻は正確に保たれるようになる.
ダイナミックDNSのIPアドレス更新を自動化してみる [雑記]
前回,ダイナミックDNSの登録をやって,ひとまず使えるようになったのだが,必須作業であるIPアドレスの更新が手動になっていた.今回はこれを自動化してみる.
で,ちょっと調べてみると,この自動更新をやってくれるクライアントソフトがある.
Windowsでは,DiCEが定番のようだ.
だけどうちのサーバはUbuntuだ.DiCE for Linux Beta Versionというのもあるようだが,もうちょっと調べてみると,「Dynamic DO!.jp」ならスクリプトとcronで簡単にできるようだ.
参考にしたサイトは以下の3つ.
「240ねっと! - Linuxサーバの構築」
「DDNS/ddo.jp - PukiWiki」
「U1F BLOG: ddo.jp 自動更新スクリプト」
では,具体的な作業に入ろう.
まずは,perlスクリプトの作成.IPアドレスの変更があったときだけ更新(登録)作業をするようなスクリプトとしておく.
ipchk.plは以下のとおり.
ちなみに,ホスト名とパスワードは「Dynamic DO!.jp」に登録したホスト名とパスワードだ.
このスクリプトにはパスワードが平文で書かれてるので,アクセス権をrootだけにしてやる.
動作テストしてエラーが無ければcronに登録してやる.
「Dynamic DO!.jp」には以下のような記載がある.
あと,まるっきりIPアドレスが変わらないと更新(登録)作業がされないことになるが,最低1ヶ月に1回はIPアドレスの更新をしないといけない.なので,スクリプトが生成する「現在のIPアドレスを保持するファイル」を週に2回削除するようにして,必ず更新(登録)作業がされるようにしてやる.
crontabの編集
記載内容
これでIPアドレス更新が自動的に行われるようになるはずだ.
試しにサーバのIPアドレスを変更したり,CRT_IP.datファイルを削除して動作を確認してみたが正常に動作しているようだ.
ちなみにLogは/var/log/ddns.logに出力される.更新(登録)作業がされたときに出力されるようになっていて動作が確認できる.
以上で作業は完了.これでIPアドレスが変わってもちゃんとDNSでアクセスできるようになる.
で,ちょっと調べてみると,この自動更新をやってくれるクライアントソフトがある.
Windowsでは,DiCEが定番のようだ.
だけどうちのサーバはUbuntuだ.DiCE for Linux Beta Versionというのもあるようだが,もうちょっと調べてみると,「Dynamic DO!.jp」ならスクリプトとcronで簡単にできるようだ.
参考にしたサイトは以下の3つ.
「240ねっと! - Linuxサーバの構築」
「DDNS/ddo.jp - PukiWiki」
「U1F BLOG: ddo.jp 自動更新スクリプト」
では,具体的な作業に入ろう.
まずは,perlスクリプトの作成.IPアドレスの変更があったときだけ更新(登録)作業をするようなスクリプトとしておく.
cd /usr sudo mkdir ddns cd ddns sudo vi ipchk.pl
ipchk.plは以下のとおり.
ちなみに,ホスト名とパスワードは「Dynamic DO!.jp」に登録したホスト名とパスワードだ.
#!/usr/bin/perl # $CRT_IPF = '/usr/ddns/CRT_IP.dat'; $NEW_IPF = '/usr/ddns/NEW_IP.dat'; $LOG = '/var/log/ddns.log'; open (INPUT,$CRT_IPF); $CRT_IP=<INPUT>; close (INPUT); system("/usr/bin/wget -q -O $NEW_IPF http://info.ddo.jp/remote_addr.php"); open(INPUT,$NEW_IPF); @xx = <INPUT>; $c = $xx[1]; $stp = index($c,"REMOTE_ADDR:")+12; $edp = length($c); $NEW_IP = substr($c,$stp,($edp-$stp)); close(INPUT); if ($NEW_IP ne "" and $CRT_IP ne $NEW_IP) { open (OUTPUT ,">$CRT_IPF"); print OUTPUT $NEW_IP; close OUTPUT; print "IP Address update: $CRT_IP to $NEW_IP\n"; system("wget -q -O - 'http://free.ddo.jp/dnsupdate.php?dn=ホスト名.ddo.jp&pw=パスワード'"); $now_string = localtime; open (OUTPUT ,">>$LOG"); print OUTPUT "$now_string DDNS IP Address Updated. $CRT_IP to $NEW_IP\n"; close OUTPUT; }
このスクリプトにはパスワードが平文で書かれてるので,アクセス権をrootだけにしてやる.
sudo chmod 700 ipchk.pl
動作テストしてエラーが無ければcronに登録してやる.
「Dynamic DO!.jp」には以下のような記載がある.
「IPアドレス更新リクエストが毎時00分前後の数秒に集中しております。 サーバ負荷の増大に伴い、その間の更新リクエストが失敗する場合もございます。 自動更新処理は毎時00分を避けるよう設定ください。」なので5分ごとの更新タイミングを3分ずらすようにする(3分,8分,13分・・・とする).
あと,まるっきりIPアドレスが変わらないと更新(登録)作業がされないことになるが,最低1ヶ月に1回はIPアドレスの更新をしないといけない.なので,スクリプトが生成する「現在のIPアドレスを保持するファイル」を週に2回削除するようにして,必ず更新(登録)作業がされるようにしてやる.
crontabの編集
sudo crontab -e
記載内容
3-58/5 * * * * /usr/ddns/ipchk.pl 0 5 * * 0 rm -f /usr/ddns/CRT_IP.dat 0 5 * * 3 rm -f /usr/ddns/CRT_IP.dat
これでIPアドレス更新が自動的に行われるようになるはずだ.
試しにサーバのIPアドレスを変更したり,CRT_IP.datファイルを削除して動作を確認してみたが正常に動作しているようだ.
ちなみにLogは/var/log/ddns.logに出力される.更新(登録)作業がされたときに出力されるようになっていて動作が確認できる.
以上で作業は完了.これでIPアドレスが変わってもちゃんとDNSでアクセスできるようになる.
ダイナミックDNSを使ってみる [雑記]
外出してるときとかでも,いま使ってる格安サーバ(PRIMERGY MX130 S2)にアクセスできるようにしてみる.
幸い,うちはグローバルIPが割り振られてるので,IPアドレスさえ分かれば外からでもsshで接続できる.でも,IPアドレスなんて覚えられないし,残念ながら固定IPでもない.
で,こんなときはダイナミックDNSだ.
詳細はリンク先を見てもらうとして,ま,ざっくり言えば固定IPじゃなくてもDNSが使えるようになるってことだ.IPアドレスが変わったときにダイナミックDNSのサービスに通知するようにしておけばIPとDNSの対応付けをやってくれる.
ダイナミックDNSのサービスは検索すると.無料で使えるサービスがいろいろある.
で,いろいろ比較した結果,「Dynamic DO!.jp」を利用することにした.
Dynamic DO!.jpでは有料版もあるけど,いま考えてる用途なら無料版で全く問題ない.ありがたく無料版を利用させてもらう.
使い方(登録方法)はとっても簡単.特に悩むところはないと思う.検索すれば登録方法を詳しく説明してるサイトもあるようだ.
で,登録が完了すれば,ホスト名.ddo.jpが使えるようになるわけだが,サーバのIPアドレスを登録しないといけない.
とりあえず手動で設定するにはDynamic DO!.jpのサイトから「IPアドレスの更新」をすればよい.
これでDNSとIPアドレスの関係が正しく設定されることになる.
ところで,Dynamic DO!.jpの無料版だと最低1ヶ月に1回はIPアドレスの更新をしないといけない(更新がないと登録削除される).それに,そもそもサーバのIPアドレスが変わったら更新をしないといけない.
これを手動でやるのはとっても面倒だ.
で,自動化するわけだが,とりあえず今回はここまで.
自動化の作業はまた次回...
幸い,うちはグローバルIPが割り振られてるので,IPアドレスさえ分かれば外からでもsshで接続できる.でも,IPアドレスなんて覚えられないし,残念ながら固定IPでもない.
で,こんなときはダイナミックDNSだ.
詳細はリンク先を見てもらうとして,ま,ざっくり言えば固定IPじゃなくてもDNSが使えるようになるってことだ.IPアドレスが変わったときにダイナミックDNSのサービスに通知するようにしておけばIPとDNSの対応付けをやってくれる.
ダイナミックDNSのサービスは検索すると.無料で使えるサービスがいろいろある.
で,いろいろ比較した結果,「Dynamic DO!.jp」を利用することにした.
Dynamic DO!.jpでは有料版もあるけど,いま考えてる用途なら無料版で全く問題ない.ありがたく無料版を利用させてもらう.
使い方(登録方法)はとっても簡単.特に悩むところはないと思う.検索すれば登録方法を詳しく説明してるサイトもあるようだ.
で,登録が完了すれば,ホスト名.ddo.jpが使えるようになるわけだが,サーバのIPアドレスを登録しないといけない.
とりあえず手動で設定するにはDynamic DO!.jpのサイトから「IPアドレスの更新」をすればよい.
これでDNSとIPアドレスの関係が正しく設定されることになる.
ところで,Dynamic DO!.jpの無料版だと最低1ヶ月に1回はIPアドレスの更新をしないといけない(更新がないと登録削除される).それに,そもそもサーバのIPアドレスが変わったら更新をしないといけない.
これを手動でやるのはとっても面倒だ.
で,自動化するわけだが,とりあえず今回はここまで.
自動化の作業はまた次回...