インタプリタ

Linuxでは標準でperlやpythonやrubyなどのインタプリタ言語が使えます。しかし、端末からのCUIを担うシェルそのものも、インタプリタ言語と呼べるぐらいの機能を持っています。これを少しだけかじってみます。

ここでの最終目標

最終的に次の3つのコマンドを連携させてコンピュータの状態のグラフを表示します。

  1. vmstat でCPU負荷などの統計を得る
  2. gnuplot でグラフにする
  3. display でグラフを表示する

ここでの提出課題

全部で8つの課題ファイルがあります。「今回の[ ]目の課題ファイルの名前です」と書いてあるのがそれです。

また端末で操作することにより自動的に作られるファイルも課題ですから、ファイルを作るだけでなく書いてあるとおりに動作させる必要があります。

scという名前のフォルダを作ってその中で作業をします。作成するファイルはすべてscの中に作られるはずです。名前の指定のあるものは正確にその名前にしないと課題のチェックができませんので注意してください。

使用するコマンドの一覧

コマンド

ls list ファイルの一覧を表示
ls -l (long) ファイルの一覧詳細タイプ
cat concatinate テキストファイルの内容表示(連結)
vmstat virtual memory statistics 仮想メモリの統計
cd change directory カレントディレクトリを移動します
gnuplot gnu(Gnu is Not Unix) plot グラフを作る
display Image Magick という画像加工ソフトの一部 画像を表示する

リダイレクト,パイプなど

> 出力のリダイレクト 本来画面へ出力されるものを>の右のファイルなどに出力する
>> 出力の追加リダイレクト >の右がファイルの場合、新規のファイルにせず追加にする
< 入力のリダイレクト 本来キーボードから入力するものを<の右のファイルなどから入力する
<< ヒアドキュメント 本来キーボードからの入力するものをスクリプト中に書くときに使用する。
| パイプ 左側のコマンドの出力を右側のコマンドに入力させる。
\ バックスラッシュエスケープ 次の1文字を特別な扱いにする
(\nを改行にしたり、行末で改行をないものと見なしたり)。

0.準備とウォーミングアップ

まず、scというフォルダをユーザーホームの中に作ります。(GUIから作って構いません)

端末を[アプリケーション]-[アクセサリ]-[端末]で開きます。次のようにプロンプトが出ます。

z2c1f@star00:~$

$の直前に注目してください。

~はユーザーホームの印です。

scフォルダの内部に移動します。scフォルダを作ってあることを確認して cd sc と命令します。

z2c1f@star00:~$ cd sc
z2c1f@star00:~/sc$

~~/scになったことを確認してください。「bash: cd: sc: そのようなファイルやディレクトリはありません」と言われたら、フォルダを作ってからもう一度。

1.システムの状態をグラフで表す

1-1.vmstatとは

vmstatはメモリの使用状況やCPUの使用時間を報告するコマンドです。次のようにすると1秒間隔で10回報告します。

vmstat 1 10

結果は例えば次のようになります。

z2c1f@star00:~/sc$ vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0      0 770128  51356 624508    0    0    15     2  386  683  6  2 92  1
 0  0      0 769996  51356 624508    0    0     0     0  630 1141  4  2 94  0
 0  0      0 769996  51356 624508    0    0     0     0  673 1189  5  1 94  0
 2  0      0 769996  51356 624508    0    0     0     0  610 1112  4  1 94  0
 0  0      0 769996  51356 624508    0    0     0     0  655 1151  4  2 93  0
 0  0      0 769996  51356 624508    0    0     0     0  846 1615  5  2 93  0
 0  0      0 770120  51364 624508    0    0     0    28 1278 2398  4  1 95  0
 0  0      0 770120  51364 624508    0    0     0     0  864 1624  4  1 95  0
 0  0      0 770120  51364 624508    0    0     0     0  655 1184  4  2 94  0
 0  0      0 770120  51364 624508    0    0     0     0  616 1112  4  1 95  0

それぞれの項目の意味です。変化があってグラフにしがいがあるものだけ日本語で示しました。

Procs
   r: The number of processes waiting for run time.
   b: The number of processes in uninterruptible sleep.

Memory
   swpd: the amount of virtual memory used.
   free: the amount of idle memory.
   buff: the amount of memory used as buffers.
   cache: the amount of memory used as cache.
   inact: the amount of inactive memory. (-a option)
   active: the amount of active memory. (-a option)

Swap
   si: Amount of memory swapped in from disk (/s).
   so: Amount of memory swapped to disk (/s).

IO
   bi: (HDDから読んだ量/秒)Blocks received from a block device (blocks/s).
   bo: (HDDに書いた量/秒)Blocks sent to a block device (blocks/s).      

System
   in: The number of interrupts per second, including the clock.
   cs: The number of context switches per second.

CPU
   These are percentages of total CPU time. (%表示だよ)
   us: (ユーザーが使った時間)Time spent running non-kernel code. (user time, including nice time)
   sy: (システムが使った時間)Time spent running kernel code. (system time)
   id: (休んでいる時間)Time spent idle. Prior to Linux 2.5.41, this includes IO-wait time.
   wa: (入出力待ちの時間)Time spent waiting for IO. Prior to Linux 2.5.41, included in idle.

vmstatの実行中に別のソフトを起動してみると数値が大きく変わります。回数を20にしてやってみます。

z2c1f@star00:~/sc$ vmstat 1 20
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 756500  51520 630652    0    0    14     2  384  681  6  2 92  0
 0  0      0 756492  51520 630652    0    0     0     0  983 2012  3  1 96  0
 0  0      0 756492  51520 630652    0    0     0     0  650 1324  4  1 94  0
 1  0      0 756492  51536 630692    0    0    56     0  611 1115  5  1 91  2
 0  1      0 756368  51548 631080    0    0   384     0  736 1533  6  2 91  1
 0  1      0 746104  51660 638476    0    0  7156     0 1590 2852 17  5 48 30
 2  0      0 736504  51800 642092    0    0  3644   220 1642 2283 30  8 48 15
 1  0      0 733044  51864 643060    0    0   772     0 5958 10995 38 13 45  4
 0  1      0 732416  51924 643360    0    0   432     0 4837 9360 36  9 48  7
 1  0      0 724648  51932 643980    0    0   468     0 1229 1931 47  3 46  5
 0  0      0 722268  51932 644364    0    0     0     0 1020 4547 27  4 69  0
 0  0      0 722268  51944 644364    0    0     4   324  708 1284  6  2 92  1
 1  0      0 722268  51944 644364    0    0     0     0  354  638  4  3 94  0
 0  0      0 722268  51944 644364    0    0     0     0  602 1072  4  1 95  0
 0  0      0 722268  51944 644360    0    0     0     0  539 1013  2  1 98  0
 0  0      0 722268  51944 644364    0    0     0     0  326  575  2  1 97  0
 0  0      0 722268  51952 644356    0    0     0    32  293  530  2  1 97  0
 1  0      0 722268  51952 644364    0    0     0     0  357  615  2  1 96  0
 0  0      0 722268  51952 644364    0    0     0     0  287  498  2  1 97  0
 0  0      0 722268  51952 644364    0    0     0     0  332  584  2  1 97  0

1-2.データをファイルに書きこむ

> vvv1 と加えるだけで、vvv1というファイルに結果を出力します(画面にはでなくなります)。20秒かかりますからその間に gimp や calc などのソフトを起動して負荷をかけてみてください。vvv1は今回の課題ファイルの名前です。

z2c1f@star00:~/sc$ vmstat 1 20 > vvv1
z2c1f@star00:~/sc$

20と>の間にスペースが必要です。普通あってもなくても大丈夫なものなのですが。

できたかどうかは次のように確認できます。

z2c1f@star00:~/sc$ cat vvv1
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 756500  51520 630652    0    0    14     2  384  681  6  2 92  0
 0  0      0 756492  51520 630652    0    0     0     0  983 2012  3  1 96  0
 0  0      0 756492  51520 630652    0    0     0     0  650 1324  4  1 94  0
 1  0      0 756492  51536 630692    0    0    56     0  611 1115  5  1 91  2
 0  1      0 756368  51548 631080    0    0   384     0  736 1533  6  2 91  1
 0  1      0 746104  51660 638476    0    0  7156     0 1590 2852 17  5 48 30
 2  0      0 736504  51800 642092    0    0  3644   220 1642 2283 30  8 48 15
 1  0      0 733044  51864 643060    0    0   772     0 5958 10995 38 13 45  4
 0  1      0 732416  51924 643360    0    0   432     0 4837 9360 36  9 48  7
 1  0      0 724648  51932 643980    0    0   468     0 1229 1931 47  3 46  5
 0  0      0 722268  51932 644364    0    0     0     0 1020 4547 27  4 69  0
 0  0      0 722268  51944 644364    0    0     4   324  708 1284  6  2 92  1
 1  0      0 722268  51944 644364    0    0     0     0  354  638  4  3 94  0
 0  0      0 722268  51944 644364    0    0     0     0  602 1072  4  1 95  0
 0  0      0 722268  51944 644360    0    0     0     0  539 1013  2  1 98  0
 0  0      0 722268  51944 644364    0    0     0     0  326  575  2  1 97  0
 0  0      0 722268  51952 644356    0    0     0    32  293  530  2  1 97  0
 1  0      0 722268  51952 644364    0    0     0     0  357  615  2  1 96  0
 0  0      0 722268  51952 644364    0    0     0     0  287  498  2  1 97  0
 0  0      0 722268  51952 644364    0    0     0     0  332  584  2  1 97  0

思うように数値が変化していなければ、 vmstat 1 20 > vvv1 を何度かやって別のソフトを起動して cat で調べます。

1-3.gnuplotを起動してグラフを描かせる

gnuplot を起動します。これはグラフ作成ソフトです。

z2c1f@star00:~/sc$ gnuplot

    G N U P L O T
    Version 4.4 patchlevel 0
    last modified March 2010
    System: Linux 2.6.32-5-686

    Copyright (C) 1986-1993, 1998, 2004, 2007-2010
    Thomas Williams, Colin Kelley and many others

    gnuplot home:     http://www.gnuplot.info
    faq, bugs, etc:   type "help seeking-assistance"
    immediate help:   type "help"
    plot window:      hit 'h'

Terminal type set to 'wxt'
gnuplot> 

上の図でこの色の部分は gnuplot の自己紹介や著作権表示です。(実際には色が変わるわけではありません)

プロンプトが、z2c1f@star00:~/sc$ から gnuplot> に変わりました。

このプロンプトが出ているときは gnuplot を使っている時です。

グラフを描かせるコマンドを入力します。

gnuplot> plot "vvv1" using :13 with lines

ウインドウが開いてグラフが出ます。

plot "vvv1" using :13 with lines
描画 ファイルvvv1の 13番目のデータ 折れ線で

項目と番号の関係の一覧です。数値を変更して色々なグラフがかけることを確認してください。

 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  2   3      4      5     6       7    8     9     10   11   12 13 14 15 16

グラフの描画後はグラフのウィンドウにフォーカスが移っています。端末をクリックしてフォーカスを戻せば次のグラフの指示ができます。

グラフのウィンドウの閉じるボタン(ウインドウ隅の[×])で閉じてもOKです。

gnuplotを終わるときには、exitまたはquitと指示します。

gnuplot> exit
z2c1f@star00:~/sc$ 

1-4.gnuplotにいろいろ指示する

2つの項目についてグラフを描くには

gnuplot> plot "vvv1" using :13 with lines,"vvv1" using :14 with lines

plot "vvv1" using :13 with lines , "vvv1" using :14 with lines
描画 ファイルvvv1の 13番目のデータ 折れ線で そして ファイルvvv1の 14番目のデータ 折れ線で

凡例の文字列も指定できます。

gnuplot> plot "vvv1" using :13 title "us" with lines,"vvv1" using :14 title "sy" with lines

plot "vvv1" using :13 title "us" with lines , "vvv1" using :14 title "sy" with lines
描画 ファイルvvv1の 13番目のデータ 見出しを us で 折れ線で そして ファイルvvv1の 14番目のデータ 見出しを sy で 折れ線で

1-5.gnuplotに指示する内容をファイルに書いておける

gnuplotを起動してから指示するのは、いつも同じグラフを書くときには不便です。いつも書く書類はワープロで作っておけばすぐに出せます。同様にグラフも書き方をファイルに書いておいてgnuplotに読ませればいいのです。

次のような内容のファイルをエディタ(gedit)で作ってください。

ファイル名 pdata1

set terminal png size 640,400
set output "graph1.png"
plot "vvv1" using :13 title "us" with lines,"vvv1" using :14 title "sy" with lines

pdata1 は今回の2つ目の課題ファイルの名前です。

1行目はグラフを直接画面に出さないで、png形式のファイルに書きだすという指示です。

2行目は画像ファイルのファイル名の指定です。

3行目はgnuplotの中で指示したものと同じです。

最後の行は長いので、次のようにして2行に分けて書くこともできます。

set terminal png size 640,400
set output "graph1.png"
plot "vvv1" using :13 title "us" with lines,\
     "vvv1" using :14 title "sy" with lines

\ を書くとその直後の文字を無視することになっています。\の直後で改行すれば改行をなかったことにしてくれるので2行以上に分けて書けます。半角のスペースも無視されますから適当にスペースを入れて"vvv1"の位置を合わせるととても見やすくなります。

gnuplotの実行の仕方が変わります。

z2c1f@star00:~/sc$ gnuplot pdata1

これで graph1.png" という画像ファイルができます。

graph1.png は今回の3つ目の課題ファイルの名前です。

今年のデスクトップの環境では、プレビューされていますし、ダブルクリックすると eog というソフトで表示されます。

1-6.できた画像をフォルダを開いたりせずに表示する

GUIを使って出来た画像を表示できますが、仮想端末から画像の表示を指示することもできます。displayコマンドを使います。

graph1.png を 表示したいときは

z2c1f@star00:~/sc$ display graph1.png

仮想端末から実行しているのですが、別のウィンドウが開いて立派に画像が出ます。

Linuxでも環境によって display コマンドは使えないかもしれません。その場合、gnomeなら display コマンドの代わりに eog コマンドも使えます。

2.スクリプト

いままでにやったことを整理します。

  1. vmstat 1 20 > vvv1 でCPU負荷などのシステムデータをファイル vvv1 に書く。
  2. ファイルvvv1のデータをgraph1.pngにするという指示をpdata1に書く。
  3. gnuplot pdata1 でgraph1.pngを作る
  4. display graph1.png で画像を表示する

2-1. 初めてのシェルスクリプト

手順3.と4.をファイルに書いて、順番にやらせることができます。

ファイル名 plot1

#!/bin/sh
gnuplot pdata1 
display graph1.png

plot1 は今回の4つ目の課題ファイルの名前です。

ファイル名 plot1 として保存したら sh plot1 または、 . plot1 で実行できます。

z2c1f@star00:~/sc$ sh plot1

このように端末で実行するコマンドをまとめて書いたものはシェルスクリプトと呼ばれます。シェルスクリプトは一種のプログラムです。

2-2. 2つ目のシェルスクリプト

graph1.png を作りなおして表示しているのですが、 graph1.pngは始めからあるので、display しかやっていないように見えます。

では vmstat もシェルスクリプトで実行してみましょう。こうすると実行するたびに異なるグラフになります。

次のようなファイルを作って plot2 という名前で保存します。

ファイル名 plot2

#!/bin/sh
vmstat 1 20 > vvv2
gnuplot pdata2
display graph2.png

plot2 は今回の5つ目の課題ファイルの名前です。

実行する前に pdata2 を作る必要があります。

ファイル名 pdata2

set terminal png size 640,400
set output "graph2.png"
plot "vvv2" using :13 title "us" with lines,\
     "vvv2" using :14 title "sy" with lines

pdata2 は今回の6つ目の課題ファイルの名前です。

ファイル名 plot2 と pdata2 ができたら sh plot2 または、 . plot2 で実行できます。

z2c1f@star00:~/sc$ sh plot2

2-3. シェルとシェルスクリプト

Linuxの端末でコマンドを受け付けて実行するソフトウェアを「シェル」といいます。LinuxのCUIを担うものです。語源は「殻」です。OSの核の部分を殻が覆っていて人間が触れる部分、操作者の意図を核に伝えるインターフェースです。

すでにあるコマンドを組み合わせてファイルに書いておくだけで、新しいコマンドを作ることができます。そればかりか一般のプログラミング言語の様に繰り返しや条件分岐の機能も持っています。

今回のplot2は実行後20秒間のCPUの動作状態をグラフで表示するコマンドになっているわけです。

sh plot2 で書く sh がシェル(shell)の一般的な名称です。新しいシェルを起動させてplot2の内容を実行させるという意味です。

. plot2 は現在実行中のシェルにplot2の中のコマンドを実行させるという意味です。

今回のplot2ではどちらでも結果は同じですが、手段は微妙に異なります。

2-4. 余計な話

さて、コマンドというと、vmstat や cat や gnuplot や display です。前に sh や . はつきません。新しいコマンドを作ることができると言ったのに sh や . をつける必要があるというのはちょっと気に入らないという人は以下の説明を読んでください。気にならない人は読み飛ばしたほうがいいでしょう。

キーワードは実行権とパスです。

まず実行権を調べます。最初のrw-の部分に注目です。

z2c1f@star00:~/sc$ ls -l plot2
-rw-r----- 1 z2c1f z2c1f 65 2013-02-16 15:45 plot2

実行できるようにします。

z2c1f@star00:~/sc$ chmod u+x plot2

そしてもう一度確認します

z2c1f@star00:~/sc$ ls -l plot2
-rwxr----- 1 z2c1f z2c1f 65 2013-02-16 15:45 plot2

これでこのスクリプトは所有者が実行できるようになりました。

そのやり方は

z2c1f@star00:~/sc$ ./plot2

./ はカレントディレクトリにあるという意味です。. とほとんど変わりませんので実行権をあたえたメリットが感じられませんね。ごもっとも。

Linuxでは実行するプログラムを置くディレクトリを登録しておきます。「パスを通す」といいます。vmstat, gnuplot などが ./なしで実行できるのはパスが通っているところに実行ファイルがあるからです。昔はカレントディレクトリにもパスを通してありましたので、./ なしで自作のプログラムが実行できたのですが、最近はカレントディレクトリはパスの一覧から外れています。

パスに加えることも可能ですが、いろいろ考慮しなければならないこともあるので、このままにしておくのが無難です。

というわけで、sh や . で起動する方が得策です。余計な話という理由です。

3. 一つのファイルで

3-1. << を使う

plot2 と pdata2 という2つのファイルの間で画像ファイルの名前を同じにしなければなりません。これは面倒なのでシェルの機能を使って、ひとつのファイルにしてしまいます。

ファイル名 plot3

#!/bin/sh
vmstat 1 20 > vvv3
gnuplot << EOF
set terminal png size 640,400
set output "graph3.png"
plot "vvv3" using :13 title "us" with lines,\
     "vvv3" using :14 title "sy" with lines
EOF
display graph3.png

plot3 は今回の7つ目の課題ファイルの名前です。

EOF に挟まれた部分が plot2 に書かれていた内容です(ファイル名が2から3に変更になっただけです)。

正確に言えば、<< EOF が「次のEOFまでのデータをgnuplotに送れ」という意味なのです。

vvv3,graph3.pngの2つはファイル名です。" " でくくられているものとそうでないものがありますが、これはgnuplotの事情で、pdata2でもそうなっていました。

plot3 ができたら plot2と同様に sh plot3 または、 . plot3 で実行できます。

z2c1f@star00:~/sc$ sh plot3

20秒待たされるのも同じです。

3-2. 変数を使う

ファイルの名前を何度も書かなくてもいいように、変数(シェル変数)を使いましょう。

vvvname, graphname の2つがシェル変数です。=の前後に空白を入れてはいけません。大文字と小文字は区別します。参照(値を使う)時は頭に$をつけます。

名前は全部3から4になります(課題チェックのためだけです)から気をつけてください。

ファイル名 plot4

#!/bin/sh
vvvname="vvv4"
graphname="graph4.png"
vmstat 1 20 > $vvvname
gnuplot << EOF
set terminal png size 640,400
set output "$graphname"
plot "$vvvname" using :13 title "us" with lines,\
     "$vvvname" using :14 title "sy" with lines
EOF
display $graphname

plot4 は今回の8つ目の課題ファイルの名前です。

plot4 ができたら plot3と同様に sh plot4 または、 . plot4 で実行できます。

z2c1f@star00:~/sc$ sh plot4
聖愛中学高等学校
http://www.seiai.ed.jp/
Feb. 2013