Daily Grind

システム開発関連の忘備録です

Linuxでのsvnの使い方

※もしかしたらまちがってるかも


■■Linux SVN(Subversion) の使い方メモ

svn のヘルプ
svnのコマンド一覧の表示
$ snv help

●個別コマンドのヘルプは、helpの後にコマンド名を指定します。
例えばcommitコマンドなら次のようにします。
$ svn help commit


●便利な使い方の例

自分がファイルを変更したかどうかの確認。
していれば行頭にM付いて表示される。
$ svn status ファイル名

チェックアウト後(または最後のupdate以降)、誰かがファイルをコミットしの確認。
していれば * が付いて表示される。
$ svn status -u ファイル名

チェックアウト後(または最後のupdate以降)、自分が行った変更の差分があれば表示。
$ svn diff ファイル名

チェックアウト後(または最後のupdate以降)、自分が行って変更を、誰かがコミットしていればコミット後のファイルに対しての差分を表示。
自分が変更していない場合、誰かがコミットしていれば、差分が表示される。
$ svn diff -rHEAD ファイル名

最後にコミットを行った者の名前を表示。
$ svn status -v ファイル名

チェックアウト後(または最後のupdate以降)、最後にコミットを行った者の名前を表示
$ svn status -uv ファイル名


詳しくは下記を参照

■更新操作(リポジトリから作業コピーへの反映)
次のようにupdateコマンドにファイルパスまたはディレクトリパスを指定すると指定ファイルまたは
指定ディレクトリ以下が最新リビジョンに更新されます。
$ svn update パス

※パスにはディレクトリ名またはファイル名を指定します(複数可)。
※パスを省略した場合はカレントディレクトリを指定したものとみなされます。

例)更新
$ svn update Version_update
U Version_update
リビジョン 7524 に更新しました。

※更新情報の先頭文字は次の意味を持ちます
A 追加されました
D 削除されました
U 更新されました
C 衝突しています
G マージされました

■更新の事前確認
updateを行う前に更新が行われるかどうか(誰かがファイルを更新しているか)を
確認するには次のようにします。
$ svn status -u パス

※パスにはディレクトリ名またはファイル名を指定します(複数可)。
※パスを省略した場合はカレントディレクトリを指定したものとみなされます。

例)更新の事前確認
$ svn status -u
* 7521 test.c
? Test.dtf
状態の背景となるリビジョン: 7523

この例で
7521は作業コピーファイルのリビジョンを示し、
* はリポジトリに新しいリビジョンが存在することを示します。
? はSVN管理されていないファイルであることを示します。
最終行の「状態の背景となるリビジョン:」は現在のSVN管理されている最新の
リビジョン(このファイルに限らずSVN管理されている全体を含めた最新のリビジョン)が
7523であることを示します。
これらの情報から、誰かがtest.cを変更してリビジョンが上がっているので、
更新を行うとtest.cが更新され7523にリビジョンアップすることが分かります。

stausコマンドに -v オプションを付加すると誰がこのファイルを最後に書き換えた
(コミットした)かが分かります。
※パスを指定しない場合はカレントディレクトリの全ファイルについて表示されます。

例)更新の事前確認 最終コミット者の確認
$ svn status -uv test.c
* 7521 7520 tanaka test.c ←tanaka が最終コミット者です
状態の背景となるリビジョン: 7523

※パスを指定しない場合、stausの-vや-uオプションではカレントディレクトリの全ファイル
について表示されてしまうので、grepでフィルタリングすると便利です。
$ svn status -u | grep -v ? ←SVN管理外ファイルを表示しない(?を含まない行のみ表示)

$ svn status -uv | grep '^M' ←自分が変更を加えたファイルのみ表示する(行の先頭がMで始まるものを表示)。

■コミット操作
同じlinuxユーザでログインしている場合、svnのコミットユーザを指定するには -username オプションを指定します。

例)svnのユーザ名を「xxxxx」、 メッセージを「修正 #1234 #5678」としてして src/sensor/Test/test.c を修正
$ svn commit --username xxxxx -m '修正 #1234 #5678' src/sensor/Test/test.c

※一度、usernameを指定すると、以降(同一セッション?)も覚えているので毎回usernameを
指定する必要はありません(パスワードも同様)

■コミットの事前確認
commitを行う前に自分が作業コピーに加えた変更(差分)を確認するには次のようにします。
$ svn diff パス

※パスにはディレクトリ名またはファイル名を指定します(複数可)。
※パスを省略した場合はカレントディレクトリを指定したものとみなされます。

コミット時にすでに別のユーザが変更(コミット)を行っている場合は自分が行った変更と
別ユーザが行った変更が重なってしまうので、マージ処理等が行われます。
そのため、コミット前に、更新の事前確認で述べた確認を行うと変更されているかが確認できます。

例)更新の事前確認 コミット予定ファイルについて最終コミット者の確認
$ svn status -uv パス | grep '^M'

M * 7521 7520 tanaka test.c ←tanaka が既にコミットしています。
状態の背景となるリビジョン: 7523

※1行目のMは自分で作業コピーを変更したことを示します
* は誰かが変更を加えた新しいリビジョンが存在することを示します。
従って、* が表示されなければ自分の変更のみがコミットされます(ただし、
この確認からコミットまでの間に誰かがコミットしてしまう可能性は残ります)。

別ユーザが変更を行ったファイルと自分が変更したファイルとの差分の確認
$ svn diff -r HEAD パス

※-r HEADオプションを付けないと、自分が行った変更分のみ表示されます。
※パスにはディレクトリ名またはファイル名を指定します(複数可)。
※パスを省略した場合はカレントディレクトリを指定したものとみなされます。


■作業コピーを元に戻す場合
現在の作業コピーのリビジョンに戻す(自分が加えた変更を戻す)には次のようにします。
$ svn revert パス

※パスにはディレクトリ名またはファイル名を指定します(複数可)。
※パスを省略した場合はカレントディレクトリを指定したものとみなされます。
※該当ファイルを削除(またはリネーム)してから、updateしても同様の効果となります。


■■当ビルド環境での固有な問題
現在、ビルド後にSVN管理ファイルが消えてしまい更新(update)が行えない(エラーとなる)
ファイルが存在します。
その場合は、更新するパス(ディレクトリ、ファイル)を指定して更新を行ってください。
そのためメールで流れるコミット情報を確認し、こまめに更新を行っておくと便利です。

例) Product/.svnが消えた場合
Version_updateファイルがあるディレクトリへ移動して確認してもエラーとなります。

[builder@DEVenv5]$ svn status -u ←★更新の事前確認
svn: 作業コピー管理領域を含むディレクトリ 'Product/.svn' がありません

Version_updateファイルを指定すると確認できます

[builder@DEVenv5]$ svn status -u Version_update ←★パス(ファイル名)を指定しての更新の事前確認
* 7524 Version_update
状態の背景となるリビジョン: 7568

ファイル名を指定すると更新もできます

[builder@DEVenv5]$ svn update Version_update ←★パス(ファイル名)を指定して更新
U Version_update
リビジョン 7568 に更新しました。

sedコマンド(メモ)

■MemFreeのある最後の行の数値だけシェルスクリプトの変数へ取り出す方法

 pは行、'$p'で最終行

MEM_FREE_KB=`cat xxx.log | grep MemFree | sed -n '$p' | sed -e 's/[^0-9]//g'`


"-n"オプション
 文字列を置き換えた行だけを出力するには、"-n"オプションを使用する。
 "-n"オプションを使うときは、必ず"p"を合わせて使う必要がある。

NTPの同期間隔

/etc/ntp.confでntpサーバの指定に「iburst」をつける
最短で更新してくれるらしい

server 192.168.8.XXX iburst

■NTP が機能していることを確認するのは以下。

[ec2-user ~]$ ntpstat
synchronised to NTP server (64.246.132.14) at stratum 2
   time correct to within 99 ms

■NTP サーバーが認識しているピアとその状態の概要を表示するには、ntpq -p コマンドを使用します。

[ec2-user ~]$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+lttleman.deekay 204.9.54.119     2 u   15  128  377   88.649    5.946   6.876
-bittorrent.tomh 91.189.94.4      3 u  133  128  377  182.673    8.001   1.278
*ntp3.junkemailf 216.218.254.202  2 u   68  128  377   29.377    4.726  11.887
+tesla.selinc.co 149.20.64.28     2 u   31  128  377   28.586   -1.215   1.435

CentOSでIRCサーバ構築

=====================
CentOSIRCサーバ構築
=====================

2015/11/10

参考URL
■CentOS5.8(x64)でircサーバ(ngircd)を構築してチャットをやってみよう
http://assimane.blog.so-net.ne.jp/2012-11-24

■[CentOS] yum でインストールする rpm ファイルだけをダウンロードする方法
http://code.ttsoft.jp/2014/09/centos-download-package-rpm-from-yum.html

CentOSにEPELリポジトリを追加する
http://qiita.com/muniere/items/6c4923a070cbbd824f39


【環境について】

 OS:CentOS6.5 X86_64
 IRCサーバ:ngircd

0.パッケージのダウンロード
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 IRCサーバをインストールしたいサーバはインターネットにつながらないため、
 ローカルの仮想サーバにパッケージだけダウンロードし、そのパッケージを
 実環境にもっていってインストールしました。

 1~2はダウンロード用のローカル仮想環境でやっています。
 3以降はIRCを導入するサーバでの作業です。

1.リポジトリの追加
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 ngircdはデフォルトのリポジトリにはないのでリポジトリ(epel)の追加をします。

[root@localhost tmp]# wget http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm


 ダウンロードしたrpmをインストールします。

[root@localhost tmp]# rpm -ivh epel-release-6-8.noarch.rpm

2.パッケージのダウンロード
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 パッケージをダウンロードします。(/tmpにパッケージをダウンロードします)

[root@localhost tmp]# yum --enablerepo=epel install --downloadonly --downloaddir=/tmp ngircd

 ※ngircd-21.1-5.el6.x86_64.rpmとlibident-0.32-4.el6.x86_64.rpm(←依存しているパッケージ)がダウンロードされる

 IRCを導入するサーバがネットワークにつながらないので、ダウンロードしたパッケージを実環境へコピーします。


3.パッケージのインストール
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 2でダウンロードしたパッケージを、IRCを導入する実サーバにコピーします。

 パッケージをインストールします。

[root@test10-centos65 irc]# yum localinstall libident-0.32-4.el6.x86_64.rpm  ngircd-21.1-5.el6.x86_64.rpm

 ※ネットワークにつながる場合はyumでそのままインストールします。(リポジトリはepelを指定)
[root@test10-centos65 irc]# yum --enablerepo=epel install ngircd

4.ngircdの設定
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 設定ファイルを編集します。

[root@test10-centos65 irc]# cp -p /etc/ngircd.conf /etc/ngircd.conf.org
[root@test10-centos65 irc]# vi /etc/ngircd.conf

  以下のような感じで修正しました。(Listenのとこだけ修正するだけでもOKです)

  31行目(接続するためのパスワード)
  前       ;Password = abc
  後       Password = (使いたいパスワード)
  ---
  47行目(リッスンするIPアドレス)
  前       Listen = 127.0.0.1
  後       Listen = 0.0.0.0
  ※0.0.0.0にしないと、ポート(6667)が開かないらしい
  ---
  55行目(接続時のメッセージ)
  前       ;MotdPhrase = "Hello world!"
  後       MotdPhrase = "Hello world!"
  ---
  114行目(MAX接続数)
  前       ;MaxConnections = 0
  後       MaxConnections = 100
  ---
  118行目(同一IPの接続数)
  前       ;MaxConnectionsIP = 5
  後       MaxConnectionsIP = 10
  ---
  216行目(チャンネルのMAXユーザ数)
  前       ;MaxUsers = 23
  後       MaxUsers = 100

  ※ポートではデフォルトの6667にしています。
  
  
5.ngircdの起動
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ngircdを起動します。

[root@test10-centos65 irc]#  /etc/rc.d/init.d/ngircd start

  LimeChatから接続してみましょう。

6.ngircdの自動起動
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  接続が良好であれば、自動起動を設定します。

[root@test10-centos65 irc]#  chkconfig ngircd on
[root@test10-centos65 irc]#  chkconfig --list ngircd
                        ngircd          0:off   1:off   2:on    3:on    4:on    5:on    6:off

DNSサーバ構築

CENTOS+BINDで構築した。

参考ページ
http://www.server-world.info/query?os=CentOS_6&p=dns&f=1

DNSサーバのIP:192.168.29.200
DNSサーバ名:dlp.gouriki.com
ドメイン:gouriki.com


1.BINDインストール
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

[root@dlp ~]#
yum -y install bind bind-utils 

2.BINDの設定
 ̄ ̄ ̄ ̄ ̄ ̄ ̄

[root@dlp ~]#
echo 'OPTIONS="-4"' >> /etc/sysconfig/named # IPv6を使わない場合は設定 ( 使うなら設定しない )

/etc/named.conf を以下のように編集した。

//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
	listen-on port 53 { any; };
//	listen-on port 53 { 127.0.0.1; };
//	listen-on-v6 { none; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
	// 問い合わせを許可する範囲 ( 内部ネットワーク等を指定 )
	allow-query     {
		localhost; 
		192.168.29.0/24;
	};
	// ゾーン情報の転送を許可する範囲 ( セカンダリDNSがいればその場所/範囲 )
	allow-transfer { localhost; 192.168.29.0/24; };
	recursion yes;

	dnssec-enable yes;
	dnssec-validation yes;
	dnssec-lookaside auto;

	/* Path to ISC DLV key */
	bindkeys-file "/etc/named.iscdlv.key";

	managed-keys-directory "/var/named/dynamic";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

//zone "." IN {
//
//	type hint;
//	file "named.ca";
//};

view "internall" {
        match-clients {
                localhost;
                192.168.29.0/24;
        };
        zone "." IN {
                type hint;
                file "named.ca";
        };

		include "/etc/named.rfc1912.zones";
		include "/etc/named.root.key";

        zone "gouriki.com" IN {
                type master;
                file "gouriki.com.lan";
                allow-update { none; };
        };
        zone "29.168.192.in-addr.arpa" IN {
                type master;
                file "29.168.192.db";
                allow-update { none; };
        };
};

3.内部向け正引き情報の設定ファイル作成
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

/var/named/gouriki.com.lan を以下のように作成。

$TTL 86400
@   IN  SOA     dlp.gouriki.com. root.gouriki.com. (
        2014080201  ;Serial
        3600        ;Refresh
        1800        ;Retry
        604800      ;Expire
        86400       ;Minimum TTL
)

        IN  NS      dlp.gouriki.com.

        IN  A       192.168.29.200

        IN  MX 10   dlp.gouriki.com.

dlp     IN  A       192.168.29.200


4.内部向け逆引き情報の設定ファイル作成
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

/var/named/29.168.192.db を以下のように作成。

$TTL 86400
@   IN  SOA     dlp.gouriki.com. root.gouriki.com. (
        2014080201  ;Serial
        3600        ;Refresh
        1800        ;Retry
        604800      ;Expire
        86400       ;Minimum TTL
)

        IN  NS      dlp.gouriki.com.

        IN  PTR     gouriki.com.
        IN  A       255.255.255.0

200      IN  PTR     dlp.gouriki.com.

5.BINDの起動
 ̄ ̄ ̄ ̄ ̄ ̄ ̄

[root@dlp ~]#
/etc/rc.d/init.d/named start

Starting named:
[  OK  ]

[root@dlp ~]#
chkconfig named on 
  ↑起動スクリプトに追加している

6.名前解決の参照先を変更
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

[root@dlp ~]#

vi /etc/sysconfig/network-scripts/ifcfg-eth0

# 自ホストに変更

DNS1=192.168.29.200
[root@dlp ~]#
/etc/rc.d/init.d/network restart 

7.正常に名前解決ができるかどうかの動作確認
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

[root@centos64 mnt]# dig dlp.gouriki.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.6 <<>> dlp.gouriki.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17542
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;dlp.gouriki.com.		IN	A

;; ANSWER SECTION:
dlp.gouriki.com.	86400	IN	A	192.168.29.200

;; AUTHORITY SECTION:
gouriki.com.		86400	IN	NS	dlp.gouriki.com.

;; Query time: 1 msec
;; SERVER: 192.168.29.200#53(192.168.29.200)
;; WHEN: Thu Jan 22 20:29:40 2015
;; MSG SIZE  rcvd: 63
[root@centos64 mnt]# dig -x 192.168.29.200

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.6 <<>> -x 192.168.29.200
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13263
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;200.29.168.192.in-addr.arpa.	IN	PTR

;; ANSWER SECTION:
200.29.168.192.in-addr.arpa. 86400 IN	PTR	dlp.gouriki.com.

;; AUTHORITY SECTION:
29.168.192.in-addr.arpa. 86400	IN	NS	dlp.gouriki.com.

;; ADDITIONAL SECTION:
dlp.gouriki.com.	86400	IN	A	192.168.29.200

;; Query time: 0 msec
;; SERVER: 192.168.29.200#53(192.168.29.200)
;; WHEN: Thu Jan 22 20:29:47 2015
;; MSG SIZE  rcvd: 104

マウントエントリの取得

struct mntent *mnt;
FILE *fp;

fp = setmntent("/proc/mounts", "r");

/* マウントエントリ数分ループ */
while ((mnt = getmntent(fp)) != NULL){


参考情報として、マウントエントリにある、proc devpts はリアルファイルシステムではない。