hacks/unix/コマン道

2011年09月12日

このエントリーをはてなブックマークに追加

参考比較: 単発curl v.s. 100分割curl

参考値とは言え、約21倍性能が増した。

内容所要時間
単発2,226秒
100分割103秒

ネットワーク帯域や検証マシンスペックによっては、もっと顕著な差が生まれるかも知れない。

検証内容
単発curl
$ time curl -s -L -o textinstall-134-x86.iso http://dlc.sun.com/osol/install/downloads/text_install/134/textinstall-134-x86.iso

real    37m6.561s
user    0m1.216s
sys     0m45.667s
100分割curl
$ time ./pararell-curl.sh http://dlc.sun.com/osol/install/downloads/text_install/134/textinstall-134-x86.iso
...(省略)...

real    1m43.885s
user    0m3.576s
sys     0m32.038s
検証環境
  • Ubuntu 10.04.3 LTS
  • bash 4.1.5
  • curl 7.19.7
レシピ
  1. 何並列で実行するのか決めておく。今回は100本。
  2. ダウンロード対象のContent-Length取得
  3. Content-Length値をもとに、curlコマンドの --range オプション でcurlコマンド毎に担当範囲を指定し、バックグラウンドジョブとして実行。

    man curlより

           -r/--range 
                  (HTTP/FTP/SFTP/FILE)  Retrieve a byte range (i.e a partial docu‐
                  ment) from a HTTP/1.1, FTP or  SFTP  server  or  a  local  FILE.
                  Ranges can be specified in a number of ways.
    
                  0-499     specifies the first 500 bytes
    
                  500-999   specifies the second 500 bytes
    
                  -500      specifies the last 500 bytes
    
                  9500-     specifies the bytes from offset 9500 and forward
    
                  0-0,-1    specifies the first and last byte only(*)(H)
    
                  500-700,600-799
                            specifies 300 bytes from offset 500(H)
    
                  100-199,500-599
                            specifies two separate 100-byte ranges(*)(H)
    
  4. 全ジョブが完了するまで待機
  5. 分割ダウンロードされたファイルを結合
ソースコード

レシピをもとにラッパースクリプトを作成。

使い方

第一引数を指定しない場合、CentOS 6.0のISOイメージがダウンロード対象となる。

$ git clone git://gist.github.com/1205668.git
$ ./pararell-curl.sh
$ ./pararell-curl.sh http://mirror.3tier.com/centos/6/isos/i386/CentOS-6.0-i386-bin-DVD.iso
参考文献
あと書き

分割によってこれほどの性能差が生まれるとは思っても見なかった。

続きを読む


編集
@hansode at 15:50|PermalinkComments(0)TrackBack(0)

2011年08月13日

このエントリーをはてなブックマークに追加

サーバを新調する度に幾つものコマンドを実行するのか?

新プロジェクトが発足する度に開発環境が用意される事は、良くあるはずだ。 そして、その度に、使い慣れた環境へと変身させる作業が発生するはずだ。 中には何も設定しない人も居るのだろうか? 何も無い環境だと、どうしても作業し辛い。その要因の大半は、いつもの使い慣れた環境とは違うからだ。

数年前、CodeReposdotfilesとして個人環境設定を登録する流れが発生した。この流れに自分も少し乗っかり、emacsの設定をコミットしてみた。 使い慣れた環境の設定を登録しているだけだったので、その時には気付いていない、新規調達サーバ・開発環境をリプレースした際、素早く環境整理する仕掛けまでは用意していない自分が居た事に。

きっかけは開発環境の移行

Wakame-VDCの開発をアメリカからしてる時の事。アメリカの通信回線の細さに対し次第にストレスを感じ始める。Wakame-VDCの開発環境は、東京事務所内に置いてある物理サーバを使っていたのだ。これまでの開発スタイルは、

  • 開発サーバへSSH接続してログイン
  • emacsでプログラムを書く
  • コマンドラインでコンポーネントを起動・停止

これをアメリカから行っていると、日本の10年以上前のダイアルアップ接続をしていた頃の様な速度になる時がある。YouTubeで動画を見たり、OSのインストールイメージをダウンロードしている時だ。東京に居たら考えられない事が、アメリカの通信事情では起こり得る。

通信状況に不満を覚えた自分は、『手元のラップトップに開発環境を構築してしまえば解消するはずだ。』 そう思い、開発環境移行に着手した。開発に必要となるOSは2つで、UbuntuOpenSolaris。 Windows 7にインストールしたVirtualBoxで仮想マシンを用意し、2つのOSをインストール。ここまでは実に順調だ。しかし、この後だ。開発環境整理が待ち受けていた訳だ。

  1. GitHubにdotfilesを作成、コミット
  2. dotfileをデプロイする仕掛け・・・が無い
  3. デプロイする仕掛けをシェルスクリプトで作り始めた

これらが、スクリプト作成に着手するまでに至る過程だ。

異なるOS、異なるユーザー名に対応させる

OSが2種類あり、作業するUNIXユーザー名も違う。いつも同じユーザー名を使えるとは限らない。 汎用性を重要視し、下記3つの事に注意してスクリプトを書き上げ、Gistに登録した。(※スクリプトのソースコードは、エントリ後半に埋め込んである。)

  • OSに依存しない事
  • ユーザー名に依存しない事
  • ファイルシステムのフルパスに依存しない事

スクリプトを実行しさえすれば、使い慣れた環境の一歩手前、必要最低限の環境が手に入る。 一歩手前なのかは、アプリケーションインストールまでを行わないからだ。

スクリプト化した事により、新環境へ移行せざるを得ない状況になっても一撃必殺で作業が終わる。 細かい制約を挙げると、事前にGitをインストールしておく必要がある訳だが…大した問題ではない。 スクリプト化後は、大幅に作業工数が減った。

ギーク達がどのように個人的開発環境を新規構築しているのかが気になる。 『開発環境構築手順を晒すブーム』が到来してくれないだろうか?

あと書き
変化を好機と位置づけ、それを楽しめ
個人的な環境を構築するスクリプト

この環境は個人使用に特化しているので、万人が使って幸せになれる訳ではない。

詳解 シェルスクリプト
Arnold Robbins Nelson H. F. Beebe
オライリージャパン
売り上げランキング: 95612



編集
@hansode at 15:00|PermalinkComments(0)TrackBack(0)

2011年01月28日

このエントリーをはてなブックマークに追加

facterを調べていたらfactorを発見

Puppetが利用しているライブラリfacterを調べていたら、タイポして「factor」を実行してしまった事がキッカケ。

factorは、因数分解する為のコマンド

実行してみれば分かる。

▼整数1〜25を確認

$ for i in {1..25}; do factor ${i}; done
1:
2: 2
3: 3
4: 2 2
5: 5
6: 2 3
7: 7
8: 2 2 2
9: 3 3
10: 2 5
11: 11
12: 2 2 3
13: 13
14: 2 7
15: 3 5
16: 2 2 2 2
17: 17
18: 2 3 3
19: 19
20: 2 2 5
21: 3 7
22: 2 11
23: 23
24: 2 2 2 3
25: 5 5

素数の場合、素因数には1つだけ数値が現れる。

▼素数だけ表示してみる

素数の場合、1行に対する表示項目数が「2」となる性質を利用して素数だけを表示する。
沢山表示しても仕方が無いので、200までの素数を表示してみる。

$ for i in {2..200}; do factor ${i} | awk 'NF == 2'; done
2: 2
3: 3
5: 5
7: 7
11: 11
13: 13
17: 17
19: 19
23: 23
29: 29
31: 31
37: 37
41: 41
43: 43
47: 47
53: 53
59: 59
61: 61
67: 67
71: 71
73: 73
79: 79
83: 83
89: 89
97: 97
101: 101
103: 103
107: 107
109: 109
113: 113
127: 127
131: 131
137: 137
139: 139
149: 149
151: 151
157: 157
163: 163
167: 167
173: 173
179: 179
181: 181
191: 191
193: 193
197: 197
199: 199

▼素数を除外して表示してみる

除外するだけなので「2」ではない物を表示すれば良い。
該当数が多いので、今回は「100」までとする。

$ for i in {2..100}; do factor ${i} | awk 'NF != 2'; done
4: 2 2
6: 2 3
8: 2 2 2
9: 3 3
10: 2 5
12: 2 2 3
14: 2 7
15: 3 5
16: 2 2 2 2
18: 2 3 3
20: 2 2 5
21: 3 7
22: 2 11
24: 2 2 2 3
25: 5 5
26: 2 13
27: 3 3 3
28: 2 2 7
30: 2 3 5
32: 2 2 2 2 2
33: 3 11
34: 2 17
35: 5 7
36: 2 2 3 3
38: 2 19
39: 3 13
40: 2 2 2 5
42: 2 3 7
44: 2 2 11
45: 3 3 5
46: 2 23
48: 2 2 2 2 3
49: 7 7
50: 2 5 5
51: 3 17
52: 2 2 13
54: 2 3 3 3
55: 5 11
56: 2 2 2 7
57: 3 19
58: 2 29
60: 2 2 3 5
62: 2 31
63: 3 3 7
64: 2 2 2 2 2 2
65: 5 13
66: 2 3 11
68: 2 2 17
69: 3 23
70: 2 5 7
72: 2 2 2 3 3
74: 2 37
75: 3 5 5
76: 2 2 19
77: 7 11
78: 2 3 13
80: 2 2 2 2 5
81: 3 3 3 3
82: 2 41
84: 2 2 3 7
85: 5 17
86: 2 43
87: 3 29
88: 2 2 2 11
90: 2 3 3 5
91: 7 13
92: 2 2 23
93: 3 31
94: 2 47
95: 5 19
96: 2 2 2 2 2 3
98: 2 7 7
99: 3 3 11
100: 2 2 5 5

何のパッケージに入っている?

イマイチ使い所の分からないfactorコマンドは何なのか。

▼何のパッケージか確認

$ dpkg -S `which factor`
coreutils: /usr/bin/factor

coreutils?!
coreutilsと言えば、mv, rmなど、コアコマンド群のパッケージ。
そんなパッケージに入っているfactorコマンド。

factorコマンドの素敵な使い方をご存知の方が居らっしゃいましたら、是非、情報提供をお願いします。




編集
@hansode at 16:30|PermalinkComments(0)TrackBack(0)

2010年09月27日

このエントリーをはてなブックマークに追加

きっかけは『インスタンスを起動出来ない』と言う報告

ホームディレクトリを整理していたら出て来たスクリプト。

以前、EC2のインスタンスを起動出来ない原因を調査した。
その時の原因は、

pk.pemとcert.pemがペアではなかった事

ごく稀なケース。
複数のキーペアを管理し切れなかった結果なのだろう。

調査報告時に殴り書きしたシェルスクリプトが下記のvalidate-keypair.sh。

▼validate-keypair.sh


#!/bin/bash
#
# http://blog.hansode.org/
#
LANG=C


pk=$1
cert=$2


function usage() {
  cat <<EOS
usage:
 $ $0 [ pk.pem ] [ cert.pem ]
EOS
  exit 1
}

[ -f "${pk}" ] || usage
[ -f "${cert}" ] || usage

function gen_cert_pubkey() {
  openssl x509 -pubkey -in ${cert} -noout
}

function gen_pk_pubout() {
  openssl rsa -pubout -in  ${pk} 2>/dev/null
}

echo "generating cert pubkey..."
gen_cert_pubkey | sed 's,^,D:,'
echo "generated."

echo "generating pk pubout..."
gen_pk_pubout | sed 's,^,D:,'
echo "generated."

echo "validating..."
diff <(gen_cert_pubkey) <(gen_pk_pubout)

[ $? = 0 ] && {
  echo valid
  exit 0
} || {
  echo invalid
  exit 1
}

▼使用例


$ ./validate-keypair.sh pk-a1b2c3d4e5f6.pem cert-a1b2c3d4e5f6.pem

後書き

ファイル名の命名規則からペアであるか、ペアでないかを見分けられる。
通常、pk-*****.pem と cert-****.pem には同じ文字列が含まれている。

運用ルール等により、pk.pemとcert.pemへリネームする必要が出ると、ファイル名から推測出来なくなる。
悪意を持ってペアではないファイル名を、見た目上のペアにする事は可能。

インスタンスを起動出来ない原因追求に役に立てたら嬉しい限り。

続きを読む


編集
@hansode at 15:00|PermalinkComments(0)TrackBack(0)

2010年05月14日

このエントリーをはてなブックマークに追加

sshdとnetworkだけあれば、それでいい

検証環境で良く実行している


# chkconfig --list | egrep -v 'ssh|network' | while read svc dummy; do chkconfig --del $svc; done

必要に応じてegrepに削除除外サービスを追加すればいい。




編集
@hansode at 13:50|PermalinkComments(0)TrackBack(0)

2010年04月13日

このエントリーをはてなブックマークに追加

悪用注意

メールアプリケーション開発時には重宝する。

$ sudo tcpdump -l -s 8192 -i eth0 -w - port smtp | strings



編集
@hansode at 20:25|PermalinkComments(0)TrackBack(0)

2010年04月01日

このエントリーをはてなブックマークに追加

getoptsは使わない

久しぶりにevalを使った。

▼extract-opts.sh


#!/bin/sh

opts=""

# extract opts
for arg in $*; do
  case $arg in
    --*=*)
      key=${arg%%=*}; key=${key##--}
      value=${arg##--*=}
      eval ${key}=${value}
      opts="${opts} ${key}"
      ;;
  esac
done

# dump opts
for opt in ${opts}; do
  eval echo ${opt} : \$${opt}
done

exit 0

▼実行例


$ ./extract-opts.sh --prefix=/opt/hansode --dist=debian --version=sid --size=10
prefix : /opt/hansode
dist : debian
version : sid
size : 10



編集
@hansode at 18:00|PermalinkComments(0)TrackBack(0)

2009年05月05日

このエントリーをはてなブックマークに追加

/etc/logrotate.d/mysql-serverを見たら発見した


とあるサーバにてMySQLのログがローテートされてなかったのでDebianのlogrotate設定を参考にしてみた。
そこには見慣れないpsのオプションがあった。


$ cat /etc/logrotate.d/mysql-server
...(省略)...
                  if ps cax | grep -q mysqld; then
                    exit 1
                  fi
...(省略)...

「ps cax」?何だこれは。
axを指定する事はあっても、cを指定した事がなかった。


$ man ps
...(省略)...
       c               Show the true command name. This is derived from the
                       name of the executable file, rather than from the argv
                       value. Command arguments and any modifications to them
                       (see setproctitle(3)) are thus not shown. This option
                       effectively turns the args format keyword into the comm
                       format keyword; it is useful with the -f format option
                       and with the various BSD-style format options, which
                       all normally display the command arguments. See the -f
                       option, the format keyword args, and the format keyword
                       comm.
...(省略)...

実際にやってみよう。

cなし

$ ps ax | grep mysqld
 3033 ?        S      0:00 /bin/sh /usr/bin/mysqld_safe --skip-character-set-client-handshake
 3073 ?        Sl     0:50 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock --skip-character-set-client-handshake
 3074 ?        S      0:00 logger -p daemon.err -t mysqld_safe -i -t mysqld
17052 pts/9    S+     0:00 grep mysqld
cあり

$ ps cax | grep mysqld
 3033 ?        S      0:00 mysqld_safe
 3073 ?        Sl     0:50 mysqld

なるほど。そう言う事か。
これは便利だ。


cを知らなかった頃


今まで無駄な事をやっていた事に気づかされる。

$ ps ax | grep mysqld | grep -v grep
  • 「grep mysqld」がpsの一覧に表れてしまう
  • grepコマンドを一覧から除外するために「grep -v grep」
$ ps ax | egrep '[m]ysqld'
  • psの一覧からgrepを除外したい
  • 「egrep '[m]ysqld'」と正規表現を書く事により、
    psの結果には「egrep '[m]ysqld'」が存在し、
    「egrep '[m]ysqld'」の条件にはマッチしなくなる
  • ※grepではなくegrep

いずれの方法でも欠点があった。
mysqldのプロセスとは関係のないプロセス、たとえばファイル名に「mysqld」が含まれるファイルを編集しているプロセスがあった場合にマッチしてしまう。

これをすっきり解決する方法が「cオプション」だった。

続きを読む


編集
@hansode at 19:35|PermalinkComments(0)TrackBack(0)

2009年03月06日

このエントリーをはてなブックマークに追加

[コマン道]printf コマンドを少しつかったより

echoは不要ですよ。
printfに「\n」を使ったものが下記の通り。


$ for i in `seq 1 10` ; do printf "%02d\n" $i ; done
01
02
03
04
05
06
07
08
09
10



編集
@hansode at 16:30|PermalinkComments(2)TrackBack(0)

2009年02月06日

このエントリーをはてなブックマークに追加

コマン道魂に火をつけてくれる

コマンドラインで使える超絶便利なワンライナーを投稿・共有できる『Command-line-fu』にて紹介されていた「Command-line-fu」が面白い。
世界中のコマン道の技を閲覧可能なのだから…。

右カラム中断の「Popular functions」が興味深い。
どのコマンドが一番使われているかをタグクラウドで見える化されている。
grepは強いなぁ。

まずはアカウント作成した。
普段何気なく実行している1ライナーを登録してみよう。




編集
@hansode at 11:55|PermalinkComments(0)TrackBack(0)