より便利なUIとして登場したGUIだが、あらゆる場面で有効というわけではない。今回はコマンドベースで操作するCUIがどんなときに便利なのか、実例を挙げながら再確認してみたい。
最近では、GUIのおかげでマウスをグリグリと動かしていれば大抵のアプリケーションが実行できるし、使えるコマンドはあらかじめメニューとして用意されているという便利な世の中です。
しかし、GUIにも弱点はあります。オブジェクトやメニューを選択するときはマウス、文字を入力するときはキーボードというように、デバイスを使い分ける必要があります。また、結果の再利用がスマートにできない、作業の自動化が難しい、といったことが思い浮かびます。
裏を返すと、これらがCUIの便利なところというわけです。
昔はインターフェイスがキーボードしかなかったので、文字を入力してその結果を出力させるのが当たり前でした。それだけではなく、複数キーのシーケンスによってさまざまな制御を行うのです。慣れるとキーボードは見なくても打てるようになりますから、手はほとんど同じ位置に置いたままで作業できます。
作業の自動化や結果の再利用は、別にCUIだから優れているというわけではありません。しかし、Linux(というかUNIX)は伝統的に対話的な利用を重んじていたため、より便利に、より楽に使うための道具が用意されています。
GUIに対してCUIが勝っている点は、例えばMS-DOSプロンプトにおける拡張子の付け替えです。たくさんある*.jpegというファイルを*.jpgに直したいとき、エクスプローラでは1つ1つ修正することになります。ところが、MS-DOSプロンプトなら
C>ren *.jpeg *.jpg
とするだけです。GUIでも専用のプログラムを用意すれば同じことができますが、いかにも大げさです。実はLinuxのCUIでもこれほど簡単にはできなくて、MS-DOSの数少ない優位性だと思っています。
Linuxでは、OSとユーザーの間にあって対話的にコマンドを実行するプログラムを「シェル」と呼んでいます。貝殻の「shell」です。OSを包み込むような存在だからでしょうか。そして実にLinux的なアプローチとして、シェルにはさまざまな種類があります。有名どころではcshやbash、kshにzshなどです。それぞれ微妙に違っていて、熱心なファンもいます。普及度では、Linuxでデフォルトになっているbashが多いようです。
結果をスマートに再利用するための道具が、「リダイレクト」と「パイプ」です。MS-DOSでもバージョン2.11から実現されている機能なので、おなじみかと思います。
あるディレクトリに含まれているファイルの一覧をテキストファイルにしてみましょう。Windowsの場合、GUIだとエクスプローラでファイルの一覧を表示できますが、テキストファイルにする方法がありません。MS-DOSプロンプト(編注)を使えば、
C>dir > files.lst
で実現できます。
Linuxの場合も同様に、
$ ls > files.lst
とします。この辺りはWindowsユーザーにもなじみやすいでしょう。「>」を使うと、コマンドの結果の出力先を変更することができます。これがリダイレクトです。上記の例は、出力先としてfiles.lstというファイルを指定したため、dirやlsの結果が画面ではなくファイルに出力されたというわけです。
次は、ファイルとディレクトリの数を数えてみましょう。Windowsのエクスプローラで目的のフォルダを開くと、そこに含まれるファイルとサブフォルダの数がステータスバー(ウィンドウ最下部)に表示されます。MS-DOSプロンプトでは、残念ながら数を数えるためのコマンドがないのでうまくいきません。
Linuxでは、パイプを使って、
$ ls | wc
とします。wcは入力データの行数、単語数、文字数を出力するコマンドです。lsの出力の行数を数えれば、すなわちファイルとディレクトリの数というわけです。このように、あるコマンドの結果を別のコマンドに渡すのがパイプ(「|」)の機能です。MS-DOSでもおなじみの機能で、
C>dir | more
というように使ったことがあるのではないでしょうか。
次に、jpgという拡張子のファイルだけを数えてみましょう。Windowsでは、エクスプローラを起動して[表示]-[アイコンの整列]-[種類順]を実行します。並べ替えられたファイルから拡張子がjpgだけのものを選択すると、ステータスバーに数と合計容量が表示されます。
Linuxのコマンドでこれを行うなら、
$ ls *.jpg | wc
です。この辺りになると、そろそろCUIの方が簡単になってきます。
今度は、「amp」というつづりを含んだファイルがいくつあるか数えてみましょう。エクスプローラなら、目的のフォルダを右クリックして、コンテキストメニューで[検索]を使います。ここで[ファイルまたはフォルダの名前]に「amp」と入力して検索します。これで、ステータスバーにファイル数が表示されます。ただし、これはサブフォルダも再帰的に検索した結果です。カレントフォルダだけを検索するには、検索オプションを設定する必要があります。
Linuxには何通りか方法があります。一番簡単なのが、
$ ls *amp* | wc
です。ちょっとひねった方法として、
$ ls | egrep "*amp*" | wc
があります。こちらの方法だと正規表現が使えるので、複雑な指定が可能です。例えば、*.lzhあるいは*.zipファイルを両方同時に数えるなら、
$ ls | egrep "lzh|zip" | wc
とすることができます。oggとampの両方を含んだファイルを数えるなら、
$ ls | grep ogg | grep amp | wc
でしょう。
Windowsと同じように、特定のディレクトリ以下すべてを検索してカウントするなら、
$ find . -name "*amp*" -print | wc
となります。
findはちょっと変わったコマンドで、指定したディレクトリ以下をサブディレクトリも含めてスキャンし、特定の条件にマッチしたファイルを拾います。ファイル名や作成時間、サイズなど、いろいろな検索条件を指定できます。さらに、選択されたファイルを引数としてコマンドを実行することもできるという、いささか複雑なコマンドでもあります。例えば、
$ find . -name "*.bak" -exec rm {} \;
とすると拡張子がbakのファイルを削除します。Windowsだと、ファイル名で検索してその結果をすべて選択してから削除、といったところでしょうか。
今度は、各ディレクトリが消費している容量を調べてみましょう。Windowsのエクスプローラでは、[ファイル]-[プロパティ]か、コンテキストメニューの[プロパティ]で消費容量を調べられます。ただし、フォルダ1つ1つを調べなければならないし、メモを取って比較する必要があります。GUIでスマートに行うには、専用のプログラムを用意しないとダメです。Linuxでは、
$ du | sort -rn | less
で調べられます。duがハードディスクの使用量を調べるコマンドです。この出力はサブディレクトリをディレクトリエントリ順に並べたものなので、そのままでは一番容量を消費しているディレクトリは分かりません。そこで、パイプでsortコマンドに出力を渡して並べ替えます。オプションの-rnは数値として逆順に並べるという意味です。最後のlessは、入力を1画面ごとに区切って表示します。
また、とにかく消費量の多いディレクトリが分かればよいという場合は、
$ du | sort -n | tail
とすることでワースト10が分かります。tailは入力の最後を表示するコマンドです。こうした方が画面への出力が少なくなるので、ちょっとだけ実行が速くなります。
バラバラな名前の付いたファイルを連番のファイル名に直す場合を考えてみましょう。ここまでくると、Windows標準のGUIではお手上げです。1つ1つファイル名を手動で変更するしかありません(この用途に特化したソフトはありますが)。また、MS-DOSプロンプトでも、素直には実現できません。
Linuxではどうかというと、ちょっと呪文じみてきますが次のようにすれば実現できます。
$ declare -i i=1 $ for file in *.jpg > do > mv $file $i.jpg > i=i+1 > done
次回で詳しく説明する予定ですが、環境変数とforループの組み合わせを利用しています。
最後に、デジタルカメラで撮影したデータなどをWebで公開することを考えてみましょう。もともとのデータが1600×1200ピクセルだったりすると、これをいきなり見せるのはひんしゅくものです。640×480ピクセルくらいに変換し、さらにサムネイル用のデータも作った方がいいでしょう。
GUIでは、いちいちファイルをオープンして画像サイズを変えて上書き保存、の繰り返しが一般的です。画像が5つ程度であればこれでも構いませんが、100、200、……となると気が遠くなります。中にはまとめて変換するソフトもありますが、ほかに応用が利きません。
わたしが普段Linuxで使っているのは、ImageMagickというパッケージに含まれているconvertコマンドです。このコマンドは、ファイルフォーマットの変換と画像サイズの変換が行えます。そこで、オリジナルのデータをorgというサブディレクトリに入れておいてから、
$ cd org $ for file in *.jpg > do > convert -size 640x480 $file ../$file > done
としてサイズを640×480ピクセルにします。続けて、
$ cd .. $ for file in *.jpg > do > convert -size 20%x20% $file ${file%jpg}png >done
でサムネイル用に縦横それぞれ20%に縮小したPNGファイルを作成します。convertコマンドの引数に、何やら訳の分からない表記がありますが、これは次回で説明します。
実のところ、これらはCUIではなくLinuxの便利な点だというのは前述したとおりです。ちょっと偉そうに書くと、
といったところがLinuxのスタンスです。システム全体がこの発想に裏打ちされているからこそ、パイプやリダイレクトによってツールを組み合わせて使えるのです。
データが構造を持たないということは、処理速度の点では不利です。余分な出力を行わないということは、人間から見れば分かりにくいということです。しかし、これらを補って有り余る利点がパイプとリダイレクトにはあるのです。
次回はbashにフォーカスを当てて、もっと詳しい使い方を紹介する予定です。
Copyright © ITmedia, Inc. All Rights Reserved.