Upload
ryuichi-ueda
View
4.187
Download
4
Embed Size (px)
DESCRIPTION
Linux女子部第二回勉強会 USP友の会の発表。表題と内容が微妙に異なり、CUIでのawkの使い方中心です。
Citation preview
2011 7 2年 月 日 LINUX第二回 女子部勉強会
ビル・ゲイツも知ってる!?シェルスクリプトでLinuxを
256倍使いこなそう!!
USP友の会 上田隆一
2011 7 2年 月 日 LINUX第二回 女子部勉強会 2
contents
● -1. USP友の会の紹介● 0. 自己紹介● 1. Linux使いの嗜み、シェルスクリプト● 2. awkをシェルスクリプトで使い倒す
● (一部、ユニケージの話)
● 3. まとめ
2011 7 2年 月 日 LINUX第二回 女子部勉強会 3
-1. USP友の会● シェルスクリプト(CUI)のコミュニティー
● USP: universal shell programming
● 会員数:もうすぐ200人(200人目に粗品贈呈)
● 会の綱領● 「酒は呑め呑め呑むならば(嘘)」
● 「本物の技術・本物の人」
派手なウェブサイト
雑誌:USPマガジン
2011 7 2年 月 日 LINUX第二回 女子部勉強会 4
遊びにきてね
● イベント● 8月2日(火):定例会@東京湾納涼船
● 8月13日(土):某イベントでUSPマガジンを売る– 東京ビッグサイト 東2 ホール S-53b
● 8月末:勉強会● 9月22日(木):Tech LION vol. 3
● ネット・メディア● Twitter @usptomo(残念な駄洒落のみ)● Facebook 「USP友の会」(イベント等の告知)
2011 7 2年 月 日 LINUX第二回 女子部勉強会 5
0. 自己紹介● 上田隆一
● 1978年生まれ33歳● 博士(工学)
– 学位論文:State-Action Map Compression by using Vector Quantization for Decision Making of Autonomous Robots
● 26歳~30 →歳:東大で常勤の助手 助教
– 新人賞のようなものをぽちぽち受賞
– 教科書の翻訳(確率ロボティクス)
● 31歳:やりたいことに能力がついていかず、大学を辞める– USP研究所のやっていることが面白くて入社
2011 7 2年 月 日 LINUX第二回 女子部勉強会 6
興味・野望
● シェルスクリプト, CUI一行野郎● もともとwindowsで研究のプログラムを書いていたので新鮮
● (仮称)次世代アナログコンピュータの構想● ポテンシャル場やベクトル場等をO(1)で計算する何か
– → 非言語型の人工知能が実現 世の中ひっくり返る
● はやく10億円貯めて、物理と化学を勉強して研究にとりかかりたい– 貯金に1000年、研究に30年
● カミさんの機嫌をとる手法の研究
● 娘を真人間にする方法
2011 7 2年 月 日 LINUX第二回 女子部勉強会 7
1. Linux使いの嗜み、シェルスクリプト
● UNIXの生い立ち● テキストはユニバーサルなフォーマット
2011 7 2年 月 日 LINUX第二回 女子部勉強会 8
UNIXの生い立ち
● 誕生:1969年
● UNIXが乗った最初の計算機● DEC PDP-7(1965年発売)● メモリ:9kB~144kB
– http://www.linfo.org/pdp-7.html
PDP-7 (wikipediaより引用)
2011 7 2年 月 日 LINUX第二回 女子部勉強会 9
UNIXのテキスト文化● UNIX(Linux)は、文字で設定を行う
● 例:
● 文字はメモリを食う
● on/offの設定:ゼロイチだと1bit、「on」「off」だと最大24bitで24倍
– バイナリ: 1
– 文字(ASCIIコード): 11011110110011001100110
● PDP-7では深刻な問題になりうる
● なぜ、文字を選んだ???
2011 7 2年 月 日 LINUX第二回 女子部勉強会 10
テキストは便利
● CUIしか無かった:人間が設定を書きやすい。● 今はGUIがあるが、それでも文字の設定ファイルを利用● ↑単なるレガシーなのか??
● コマンド+パイプ● 何でもcat, grep, moreで確認● バイナリファイル:専用のエディタが必要
– バグ・無理な拡張の巣窟、プログラムが肥大
2011 7 2年 月 日 LINUX第二回 女子部勉強会 11
バイナリは(儲かるかもしれないが本質的には)面倒
● 例えば、専用バイナリ形式のワープロソフトを考える● そのワープロ専用の機能がたくさん
– 文字列検索・置換機能、文字数カウント機能、スペルチェッカー、画像埋め込み機能・・・
● アプリケーション1個に対して機能がO(n)個
● TeXを考える● テキストファイルをdviにできればそれでよい。● アプリケーション1個に対して機能はO(1)個
2011 7 2年 月 日 LINUX第二回 女子部勉強会 12
偉い人も、言っている● UNIX 哲学 [Gancarz2001]
● 小さいものは美しい。
● 各プログラムが一つのことをうまくやるようにせよ。
● できる限り原型(プロトタイプ)を作れ。
● 効率よりも移植しやすさを選べ。
● 単純なテキストファイルにデータを格納せよ。
● ソフトウェアの効率をきみの優位さとして利用せよ。
● 効率と移植性を高めるためにシェルスクリプトを利用せよ。
● 束縛するインターフェースは作るな。
● 全てのプログラムはフィルタとして振る舞うようにせよ。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 13
時代はテキスト
● 事例1:バイナリ形式のテキスト化● Office 2007
– データ形式:zipで圧縮されたxml
● 理由– バイナリフォーマットはソフト屋に抱え込まれるという世論
– 計算機が強力になった
– バイナリ形式がややこしすぎて管理できなくなった?
● 事例2:サービスのweb化● HTTPは文字でデータをやりとり
2011 7 2年 月 日 LINUX第二回 女子部勉強会 14
これからのものはテキスト主流● 最近の注目:Sphinx
● ドキュメント作成ツール
– ReST(reStructuredText)形式というテキストで作文
– webページ、pdf、ePub等様々な形式に変換してくれる
– 機能拡張に大きな可能性
● 今後の(勝手な)予想● ppmやpgmをgzip圧縮した画像が主流に?● ムービーファイルのテキスト化!(時刻、座標、rgbの羅列)
・・・だってわかりやすい方がいいじゃないですか。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 15
・・・ということで
● Linuxをいじるならば、コマンドを使ったテキスト処理に強くなろう!
● UNIX系OS使いのタシナミ● UNIX系OS使いの基礎体力
– もしかしたら今日の内容は直接役に立たないかもしれませんが、端末をいじるあらゆる局面でじわじわ効いてきます。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 16
2. awkをシェルスクリプトで使い倒す
● ログなどの処理に便利なコマンド
● awkをパイプでつなげてシェルスクリプトを書くと、かなりの種類の処理が可能になる。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 17
awk
● 古いスクリプト言語
● 開発陣● Alfred Aho →(ベル研 コロンビア大教授)
– —著書:コンパイラ 原理・技法・ツール
● Peter Weinberger →(ベル研 google)● Brian Kernighan →(ベル研 プリンストン大教授)
– 著書:プログラミング言語C
● 言語なんですが、コマンドのように使います。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 18
とりあえず使ってみる
● こんなファイル(hogeという名前)
a 100
b 20
c -10.4
● コマンドを打つ● cat hoge | awk '{print $1}'● cat hoge | awk '$1=="b"'● cat hoge | awk 'BEGIN{a=0}{a+=$2}END{print a}'
2011 7 2年 月 日 LINUX第二回 女子部勉強会 19
awkの挙動
● いかにもUNIX的(フィールド指向)● 空白で区切った表を標準入力で読み取る
● 文字列を割って$1, $2, $3, ...という変数に入れる
● 「データはこの様に持て」というメッセージ?
● 後はユーザの組んだ一行プログラムでいかようにも● 検索、計算、文字列処理・・・
2011 7 2年 月 日 LINUX第二回 女子部勉強会 20
お題A:表計算をやってみましょう● 注意:コードを追わず、何ができるかだけ、ぼんやり覚えてください。コードを追うと撃沈します。
● ファイル(hoge) 1 2 3
0.1 0.2 0.3
-1 -2 -3
● 横に足す● $ cat hoge | awk '{print $1,$2,$3,$1+$2+$3}'
1 2 3 6
0.1 0.2 0.3 0.6
-1 -2 -3 -6
2011 7 2年 月 日 LINUX第二回 女子部勉強会 21
● $0に、一行すべての文字列が入っている● $ cat hoge | awk '{print $0,$1+$2+$3}'
1 2 3 6
0.1 0.2 0.3 0.6
-1 -2 -3 -6
● 変数も使えます● $ cat hoge | awk '{sum=$1+$2+$3;print $0,sum}'
1 2 3 6
0.1 0.2 0.3 0.6
-1 -2 -3 -6
2011 7 2年 月 日 LINUX第二回 女子部勉強会 22
● 書式を整える● $ cat hoge | awk '{sum=$1+$2+$3;print $0,
sprintf("%10s",sum)}' 1 2 3 6
0.1 0.2 0.3 0.6
-1 -2 -3 -6
● 面倒なのでfor文で● $ cat hoge | awk '{$4=$1+$2+$3;for(i=1;i<=4;i++)
{printf("%5s",$i)};printf("\n")}' 1 2 3 6
0.1 0.2 0.3 0.6
-1 -2 -3 -6
2011 7 2年 月 日 LINUX第二回 女子部勉強会 23
● ややこしくなったらパイプで処理を分ける● $ cat hoge | awk '{print $0,$1+$2+$3}' |
awk '{for(i=1;i<=4;i++){printf("%5s",$i)};printf("\n")}' 1 2 3 6
0.1 0.2 0.3 0.6
-1 -2 -3 -6
2011 7 2年 月 日 LINUX第二回 女子部勉強会 24
● 縦にも足してみましょう● $ cat hoge | awk '{print $0,$1+$2+$3}' | awk
'{for(i=1;i<=4;i++){a[i]+=$i};print}END{print a[1],a[2],a[3],a[4]}' | awk '{for(i=1;i<=NF;i++){printf("%5s",$i)};printf("\n")}'
1 2 3 6
0.1 0.2 0.3 0.6
-1 -2 -3 -6
0.1 0.2 0.3 0.6
● さすがに読み返せない。どうするか?
2011 7 2年 月 日 LINUX第二回 女子部勉強会 25
シェルスクリプトにする● 基本、手で打つコマンドラインをファイルに書いただけのもの
● 便利な点● 保存できる
● コメントを書ける
#!/bin/bash#hoge.sh
cat hoge |#$1~$3: 数値#各レコードの値を足して後ろにくっつけるawk '{print $0,$1+$2+$3}' |#$1~$3: 数値 $4:合計値#各フィールドの数値を足して最終行に出力awk '{for(i=1;i<=4;i++){a[i]+=$i};print}\ END{print a[1],a[2],a[3],a[4]}'
処理を細かく区切ってデータのレイアウトだけ書いておけば、コードが読みにくくても困らない。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 26
お題B:出力にこだわる
● ところで、出力がCUI上というのは寂しい。● いや、寂しくないが、需要が多い。
● テキストの出力は貧弱?● テキストだから何にでも化けるだろう。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 27
● csv● $ ./hoge.sh | awk '{print $1,$2,$3,$4}' | tr ' ' ','
1,2,3,6
0.1,0.2,0.3,0.6
-1,-2,-3,-6
0.1,0.2,0.3,0.6–
● リダイレクトでファイルに保存– $ ./hoge.sh | awk '{print $1,$2,$3,$4}' | tr ' ' ',' > hoge.csv
2011 7 2年 月 日 LINUX第二回 女子部勉強会 28
● pukiwikiのテーブル● $ ./hoge.sh |
awk '{for(i=1;i<=NF;i++){$i = "|" $i};print $0,"|"}'|1 |2 |3 |6 |
|0.1 |0.2 |0.3 |0.6 |
|-1 |-2 |-3 |-6 |
|0.1 |0.2 |0.3 |0.6 |
● reSTのcsvテーブル● $ ./hoge.sh | awk 'BEGIN{OFS=","}{for(i=1;i<=NF;i++){$i="\""$i
"\""};print}' | awk 'BEGIN{print ".. :csv-table:: たいとる";print ""}{print "\t" $0}'
.. :csv-table:: たいとる
"1","2","3","6"
"0.1","0.2","0.3","0.6" "-1","-2","-3","-6" "0.1","0.2","0.3","0.6"
2011 7 2年 月 日 LINUX第二回 女子部勉強会 29
● HTML● $ ./hoge.sh | awk '{for(i=1;i<=NF;i++){$i = "<td>" $i
"</td>"};print}' | awk '{print "<tr>" $0 "</tr>"}' | awk 'BEGIN{print "<table>"}{print}END{print "</table>"}'
<table>
<tr><td>1</td> <td>2</td> <td>3</td> <td>6</td></tr>
<tr><td>0.1</td> <td>0.2</td> <td>0.3</td> <td>0.6</td></tr>
<tr><td>-1</td> <td>-2</td> <td>-3</td> <td>-6</td></tr>
<tr><td>0.1</td> <td>0.2</td> <td>0.3</td> <td>0.6</td></tr>
</table>
2011 7 2年 月 日 LINUX第二回 女子部勉強会 30
● HTML その2● 真面目にHTMLを書く● リダイレクトしてブラウザで閲覧– $ ./html.sh >
~/public_html/table.html
#!/bin/bash#html.shcat << FIN<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> </head> <body> <table>FINcat ./hoge |./hoge.sh |awk '{for(i=1;i<=NF;i++){$i = "<td>" $i "</td>"};print "<tr>" $0 "</tr>"}'cat << FIN </table> </body></html>FIN
2011 7 2年 月 日 LINUX第二回 女子部勉強会 31
● なにか絵に書く(xy座標へ変換)● $ ./hoge.sh |
awk '{for(i=1;i<=NF;i++){print "x=" NR, "y=" i, $i}}'x=1 y=1 1
x=1 y=2 2
x=1 y=3 3
x=1 y=4 6
x=2 y=1 0.1
x=2 y=2 0.2
x=2 y=3 0.3
x=2 y=4 0.6
x=3 y=1 -1
x=3 y=2 …
2011 7 2年 月 日 LINUX第二回 女子部勉強会 32
お題C:CGIを書く
● 各ユーザのHDD使用量を表示● du -s dir : dir以下のファイル容量を集計● HTTPヘッダを出力した後、
HTMLを出力
● POSTされたデータも読めます– ddコマンドなど
#!/bin/bash echo 'Content-type: text/html'echo ""echo '<table border="1" cellspacing="0">' du -s /home/[a-z]* 2> /dev/null |awk '{gsub(/\/home\//,"",$2);print}' |sort -k1,1nr |awk '{print int($1/1024) "MB", $2}' |awk '{print "<tr><td>" $1 "</td><td>" $2 "</td></tr>" }' echo "</table>" exit 0
2011 7 2年 月 日 LINUX第二回 女子部勉強会 33
お題D:ログを集計してみましょう
● いろいろやばい、secureログ$ head -n 5 secureJun 26 07:50:03 hoge01 sshd[12942]: Did not receive identification string from 122.176.82.13Jun 26 07:51:56 hoge01 sshd[12945]: reverse mapping checking getaddrinfo for abts-north-static-013.82.176.122.airtelbroadband.in failed - POSSIBLE BREAK-IN ATTEMPT!Jun 26 07:51:56 hoge01 sshd[12945]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=122.176.82.13 user=rootJun 26 07:51:58 hoge01 sshd[12945]: Failed password for root from 122.176.82.13 port 55020 ssh2Jun 26 07:51:58 hoge01 sshd[12946]: Connection closed by 122.176.82.13
2011 7 2年 月 日 LINUX第二回 女子部勉強会 34
まずやること● 日付正規化スクリプトを作る● 修正前
– Jun 1 10:12:30
● 修正後– 20110101 101230(ログに年が入っていないのは問題!)
● ymd.sh– 誰ですか笑っているのは?
#!/bin/bash#ymd.sh
#パイプから字を受けるcat < /dev/stdin |awk '{gsub(/Jan/,"01",$1);print}' |awk '{gsub(/Feb/,"02",$1);print}' |awk '{gsub(/Mar/,"03",$1);print}' |awk '{gsub(/Apl/,"04",$1);print}' |awk '{gsub(/May/,"05",$1);print}' |awk '{gsub(/Jun/,"06",$1);print}' |awk '{gsub(/Jul/,"07",$1);print}' |awk '{gsub(/Aug/,"08",$1);print}' |awk '{gsub(/Sep/,"09",$1);print}' |awk '{gsub(/Oct/,"10",$1);print}' |awk '{gsub(/Nov/,"11",$1);print}' |awk '{gsub(/Dec/,"12",$1);print}' |awk '{gsub(/:/,"",$3);print}' |awk '{$2=sprintf("%02s",$2);print}' | awk '{print "2011" $0}' |awk '{$1=$1 $2;$2="";print}'
2011 7 2年 月 日 LINUX第二回 女子部勉強会 35
お題D-1:一日の不正アクセス件数集計
● Failed passwordのレコードを数える● 方法1
– $ cat secure* | ./ymd.sh | awk '$5=="Failed" && $6=="password"{print $1}' | sort | awk 'BEGIN{a=0;d=0}{if(d!=$1){print d,a;d=$1;a=1}else{a++}}END{print d,a}' | tail -n +2
● 方法2(ユニケージコマンドを使う)– $ cat secure* | ./ymd.sh | awk '$5=="Failed" &&
$6=="password"{print $1}' | sort | count 1 1
2011 7 2年 月 日 LINUX第二回 女子部勉強会 36
● アタックの多かった日のランキング● $ cat secure* | ./ymd.sh | awk '$5=="Failed" &&
$6=="password"{print $1}' | sort | awk 'BEGIN{a=0;d=0}{if(d!=$1){print d,a;d=$1;a=1}else{a++}}END{print d,a}' | tail -n +2 | sort -k2,2nr | head -n 3
20110602 12525
20110613 9354
20110614 3929
● 6月2日を見てみましょう● $ cat secure* | ./ymd.sh | awk '$1==20110602' > hoge
2011 7 2年 月 日 LINUX第二回 女子部勉強会 37
お題D-2:不正アクセス検知
● 以下の場合、パスワードが破られた可能性● あるIPからのログインがやたら失敗するが、一回以上成功している。
2011 7 2年 月 日 LINUX第二回 女子部勉強会 38
#!/bin/bash
./ymd.sh < /dev/stdin |awk '$6=="password"' |awk '$5=="Failed" || $5=="Accepted"' | awk '{for(i=1;i<=NF;i++){if($i~/[0-9][0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/){print $i,$5}}}' | #$1: IP $2: Failed or Acceptedsort -k1,2 |awk 'BEGIN{str=0;c=0}{if(str!=$0){print str,c;str=$0;c=1}else{c++}}' |#$1: IP $2: Failed or Accepted $3:回数tail -n +2 | awk 'BEGIN{str=0}{if(str==$1){printf(" %s %s\n",$2,$3)}else{printf("\n%s",$0);str=$1}}' |#AcceptedとFailureが両方存在するレコードを抽出awk 'NF>3{print $1,$3,$5}' | #$1:IP $2: 成功の数 $3:失敗の数#失敗の方が回数が多いレコードを抽出awk '$2<$3'
2011 7 2年 月 日 LINUX第二回 女子部勉強会 39
● ユニケージ版#!/bin/bash
./ymd.sh < /dev/stdin |awk '$6=="password"' |awk '$5=="Failed" || $5=="Accepted"' | awk '{for(i=1;i<=NF;i++){if($i~/[0-9][0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/){print $i,$5}}}' | #$1: IP $2: Failed or Acceptedsort -k1,2 |count 1 2 |#$1: IP $2: Failed or Accepted $3:回数yarr num=1 |awk 'NF==5' |self 1 3 5 |#$1:IP $2: 成功の数 $3:失敗の数#失敗の方が回数が多いレコードを抽出awk '$2<$3'
2011 7 2年 月 日 LINUX第二回 女子部勉強会 40
お題E:データの連結(join操作)
● 次のファイルを連結● マスタ:
月(英字)と月(数字)の対応表
● トランザクション:secureログ● トランザクションにマスタをくっつけて、
Jan, Feb, Mar, ...を取り除く
Jan 01Feb 02Mar 03Apl 04May 05Jun 06Jul 07Aug 08Sep 09Oct 10Nov 11Dec 12
マスタファイル
Jun 26 07:50:03 hoge01 ...Jun 26 07:51:56 hoge01 ...Jun 26 07:51:56 hoge01 ...Jun 26 07:51:58 hoge01 ...Jun 26 07:51:58 hoge01 ...
トランザクションファイル
2011 7 2年 月 日 LINUX第二回 女子部勉強会 41
● ちなみにユニケージだとこれだけ#!/bin/bash
tmp=/tmp/$$
sort -k1,1 ./MONTHS > $tmp-master
cat ../secure* |cjoin1 key=1 $tmp-master - |delf 1
rm $tmp-masterexit 0
06 26 07:51:56 hoge01 sshd[12945]: pam_unix(sshd:auth): ...06 26 07:51:58 hoge01 sshd[12945]: Failed password ...06 26 07:51:58 hoge01 sshd[12946]: Connection closed by 122.176.82.13...
2011 7 2年 月 日 LINUX第二回 女子部勉強会 42
● awkとsortでもなんとかなる
#!/bin/bash
tmp=/tmp/$$
sort -k1,1 ./MONTHS |awk '{print $1,"00",$2}' > $tmp-months
cat ../secure* |sort -k1,1 |sort -m $tmp-months - |awk '{if($2=="00"){v=$3}else{$1=v;print}}'
rm -f $tmp-*exit 0
2011 7 2年 月 日 LINUX第二回 女子部勉強会 43
3.まとめ
● awkでテキストデータと戯れる● このスライドのawkの数:62個● 地味。腹筋なみに地味
● パズルと思えばおもしろい
● 重要:OSや基盤技術に非常に近い場所での作業– 標準入出力、ログ、HTTP、HTML、・・・
– マウスを多用するようなツールをたくさん覚えるよりは有意義
● これも重要:一緒に勉強したい方、USP友の会まで
2011 7 2年 月 日 LINUX第二回 女子部勉強会 44
4. 発表後記
● 全部awkで何とかしろということではありません● コマンドを覚えて、より短いスクリプトを書きましょう
– 短さはシェルスクリプトの最大の利点
● やりたい処理ができなかったら、その場はawkでなんとかして後からコマンドを調べる
● 言い忘れたこと● USP出版で「プログラミング言語awk」扱ってます
– http://www.usp-lab.com/pub/book.awk.html