シェルスクリプトはエレガントでなければならない:スマートな紳士のためのシェルスクリプト(1)(1/2 ページ)
UNIX系OSのユーザーなら、何らかの形で「シェルスクリプト」を使ったことがあるはずだ。人からもらったスクリプトを意味も分からずに使っているとか、コマンドを並べただけのスクリプトを使っているという人は多いだろう。この連載では、そのようなシェルスクリプト初心者を脱出して、すべてを知り尽くしたシェルスクリプトマスターとなるための手助けをしたい。(編集部)
コマンドを並べる? それだけではダメだろう
世界にはシェルスクリプトをマスターした凄腕の紳士が存在する。彼らにとってOSやディストリビューションはあくまで道具であり、シェルスクリプトはその道具を効率よく活用するための道具だ。彼らの指が紡ぎ出すスクリプトは実に合理的で、読みやすく、分かりやすく、そして効率良く動作する。そう、彼らこそシェルスクリプトマスターという名の紳士だ。
そんな紳士にあこがれを抱かずにはいられない人も多いだろう。一般人がターミナルに張り付いて、延々と長時間タイピングしなければできないような仕事を、エレガントにスクリプトにまとめて悠々とエンターキーを押して済ませてしまう姿には恍惚とせざるを得ない。自分もあんな風になりたい…… 誰しも憧れるものだ。
インターネットを少し探してみれば、シェルスクリプトの入門記事やリファレンスがいくつも見つかるし、多くの機能はマニュアルを読めば書いてある。しかし、そのようなシェルスクリプト入門から入ったユーザーの多くは、コマンドをまとめる程度のレベルで止まってしまい、そこから先の高みに登れないでいる。
入門レベルからさらに先に進むには、別の方向からのアプローチが必要だ。本連載の目的はそこにある。シェルスクリプト初心者を抜け出し、恍惚としたまなざしを受ける方になる、それがこの連載の目標だ。
先に述べたように、入門者向けの記事やリファレンスは多数存在する。本連載ではそのような部分を延々と説明することはしない。LinuxやFreeBSDが使える中級者あたりを対象としたい。コマンドの違いや環境の違い、シェルの違いなどは軽く理解できる人を想定している。そして、初心者でもやる気がある方なら十分読んでいただけるものにしていくつもりだ。
まずはPOSIX仕様を押さえること
「シェル」とは「/bin/sh」のことだ。しかし、/bin/shといってもOSによって採用しているものが異なる。主要なOS/ディストリビューションの/bin/shをまとめると表1のようになる。
OS | /bin/shの実体 |
---|---|
Mac OS X Lion | bash 3.2 |
Ubuntu 11.10 | /bin/dashへのシンボリックリンク(NetBSD ashの移植版) |
CentOS 6 | /bin/bashへのシンボリックリンク。bash 4.1 |
FreeBSD 10 | ash |
Solaris 11 | /bin/i86/ksh93へのシンボリックリンク。ksh93 |
表1 主なUNIX/Linux OSと、それぞれの/bin/shの実体 |
/bin/shの実体としてはash(dash)、bash、kshの採用例が多い。どのシェルもBourne shellの機能に加えて、拡張機能を提供する。
FreeBSDなどの*BSD系のOSは、ashを/bin/shとして使っている。ashはPOSIX.1(POSIX:2008)にいくらかのBSD拡張機能を取り込んだシェルだ。メモリをあまり消費せず、高速に動作し、ほかのライブラリに依存することが少ない。従って、rootやレスキューシステムのインタラクティブシェル、システムのシェルスクリプトといった場面で採用されている。
Mac OS Xはbashを/bin/shに採用している。FedoraやopenSUSEなどのLinuxディストリビューションもbashを/bin/shに採用している。LinuxディストリビューションでもUbuntuやDebian、Linux Mintなどは、高速に動作することを優先してBSDのashをLinuxに移植したdashを/bin/shとして採用している。Solarisは基本的にkshだ。
こうして主要なシェルを見てみると、ash/dashが最も余計な機能が少なく、POSIX.1(POSIX:2008)仕様に最も忠実だ。本連載ではash/dashを念頭に置いて説明する。とはいっても、bashやkshにも応用が利くように配慮していくので、それらのシェルを使っている方も安心してほしい。
POSIX.1(The Open Group Base Specifications Issue 7、IEEE Std 1003.1-2008、ISO/IEC 9945:2009)の仕様書はThe Single UNIX SpecificationのWebページて閲覧、ダウンロードが可能だ(ただし、ユーザー登録が必要)。POSIX.1準拠の書き方を覚えると、何かと融通が効くので、この仕様書はすぐにアクセスできるところに置いておこう。まずはPOSIX.1からだ。
賢くOSを操作するならシェルスクリプト
ここで、「なぜシェルスクリプトを使うのか」、と考える方がいるかもしれない。それは、シェルスクリプトが、OSを操作するには最も合理的な方法だからだ。Linux/FreeBSDやMac OS X、Solarisもそうだが、UNIX系のOSはカーネルを読み込んだ後、シェルスクリプトに処理を移してシステムを起動させている。シェルスクリプトは、UNIX系OSが提供する機能を利用するときに、最も便利なのだ。シェルスクリプトで利用できる機能も、扱いやすいものばかりなので、余計な心配をする必要はない。
UNIX系のOSでは、シェルスクリプトを使った既存のスクリプトが多数存在する。処理の自動化を考えるときにまず候補となる方法がシェルスクリプトだ。そうしやすい機能が整っているからだ。従来はC/C++で開発されていたツールやコマンドをシェルスクリプトで書き直す例もある。OSの提供する機能やコマンドを組み合わせるような用途では、C/C++で開発するよりもシェルスクリプトで開発した方が、素早く簡単に開発でき、変更も容易、何かと便利というわけだ。
一般的なプログラミング言語と比べると、シェル(/bin/sh)が提供する機能は貧弱だ。本格的なプログラムを開発するとき、シェルスクリプトはあまり賢い選択肢とはいえない。
もちろん、シェルスクリプトで大規模なプログラムを作れないということはない。シェルスクリプトで、オブジェクト指向プログラミングに挑戦する研究などもある。大規模なツールを、シェルスクリプトで開発する取り組みもある。しかし、それらはOSの提供する機能やコマンドをフルに活用すること自体が目的であることが多い。
マルチコア/メニーコアの時代に入りつつあるが、その面ではシェルスクリプトは興味深い側面を持っている。最近のOSはプロセスを効率よくプロセッサに割り当てて処理を進めてくれる。シェルスクリプトでパイプを活用して複数のプロセスを稼働させると、それぞれの処理をうまい具合に並列で処理できることがある。
例えばC/C++で開発したログファイル解析ツール(シングルスレッド/シングルプロセス)と、シェルスクリプトでOS標準のコマンドを組み合わせたログファイル解析スクリプト(パイプで処理を複数のプロセスへ分割)で処理性能を比較すると、マルチコア/メニーコアではシェルスクリプト版の方が処理が早く終わることがある。単一のコアしか使わないC/C++のコードと、簡単にマルチコアを活用できるシェルスクリプトの違いが最も顕著に現れるパターンだ。
シェルスクリプトとマルチコア/メニーコアは面白い組み合わせなので、この連載でも取り上げていこうと思う。またシェルスクリプトは、C/C++でコマンドを作成する際のプロトタイプとしても利用できるので、そのような使い方も詳しく説明していきたい。
Copyright © ITmedia, Inc. All Rights Reserved.