シェルスクリプトでのHello World

第2回は、シェルスクリプトを使ったHello Worldです。シェルスクリプトで任意のメッセージを表示するには、echoコマンドを使います。リスト1のように記述すると、これでシェルスクリプト版Hello Worldの完成です。なお、Hello Worldの前後をシングルクォート(' ')で囲んでいるのは、文字列中にスペースや特殊記号が含まれる場合に、それがシェルに解釈されるのを防ぐためです。

リスト1 echoコマンドを使う方法(sh_echo)

#!/bin/sh                    ← /bin/sh用スクリプトとして記述する

echo 'Hello World'           ← echoコマンドでメッセージを標準出力に出力

シェルスクリプトを実行するには、あらかじめ「chmod +x」コマンドでファイルに実行属性を付けておく必要があります(実行例1)。

実行例1 シェルスクリプトの実行

$ chmod +x sh_echo           ← シェルスクリプトのファイルに実行属性を付ける
$ ./sh_echo                  ← シェルスクリプトを実行
Hello World                  ← 確かにHello Worldが表示される
$                            ← シェルのプロンプトに戻る

printfコマンドを使う方法

echoコマンドの代わりに、printfコマンドを使うこともできます。printfは、C言語のprintf()関数に類似したコマンドで、「%s」などの書式指定つきで文字列を標準出力に出力することができます。よって、リスト2のように記述することができます。printfでは、改行は自動的には行われないため、文字列の最後に明示的に'\n'を付ける必要があります。なお、書式指定の「%s」を使わずに、単純に「printf 'Hello World\n'」としても構いません。

リスト2 printfコマンドを使う方法(sh_printf)

#!/bin/sh

printf '%s\n' 'Hello World'   ← printfを使う('\n'が必要)

別用途のコマンドを流用する方法

何らかのコマンドを、その本来の用途とは別の用途に利用し、結果的にechoコマンドの代用とすることもできます。

リスト3はbasenameコマンドを利用する方法です。basenameは、本来は、第1引数の文字列から、パス名と第2引数指定の拡張子を取り除くコマンドで、たとえば「basename /home/user/file.html .html」を実行すると、「file」という文字列が標準出力に出力されます。

basenameの第1引数に、「Hello World」のように「/」を含まない文字列を与えると、パス名に相当する部分がないため、単なるechoコマンドのように動作します。ここでは拡張子を指定する第2引数は付けません。

リスト3 basenameコマンドを使う方法(sh_basename)

#!/bin/sh

basename 'Hello World'     ← basenameをechoの代わりに流用

リスト4のようにdateコマンドを使うこともできます。dateはもちろん日時を表示/設定するためのコマンドですが、その引数に「+」で始まる書式指定文字列を付けて日時表示をカスタマイズすることができます。書式指定文字列は「%」で始まり、たとえば、12時34分56秒に「date +%H:%M:%S」というコマンドを実行すると、「12:34:56」と表示されます。

この、「+」以降の文字列として、「%」を含まない、普通の文字列を付けると、その文字列が単に表示され、結果的にechoコマンドの代用になります。

リスト4 dateコマンドを使う方法(sh_date)

#!/bin/sh

date +'Hello World'        ← dateをechoの代わりに流用(頭に「+」を付ける)

シェル以外のコマンドをシェルにする方法

シェルスクリプト1行目の「#!」の右側には、通常/bin/shなどのシェルを記述し、そのシェルにファイルを解釈させますが、ここに、シェル以外の一般のコマンドを記述することにより、変わったHello Worldのスクリプトを作ることができます。

リスト5は、tailコマンドを使う方法です。tailは、ファイルの終端から、引数で指定した行数だけを表示するためのコマンドです。このスクリプト(ファイル名はsh_tail)を実行すると、「/usr/bin/tail -1 sh_tail」というコマンドが実行され、sh_tailの最後の1行に書かれているHello Worldの文字列が そのまま出力されるという仕組みです。

リスト5 tailコマンドを使う方法(sh_tail)

#!/usr/bin/tail -1          ← tailコマンドを使ったスクリプト

Hello World                 ← ファイルの最終行にメッセージを直接記述

次に、リスト6は、grepコマンドを使う方法です。grepは、引数で指定した正規表現に一致する行のみをファイルから抜き出すコマンドです。ここでは正規表現として「^[^#]」を指定しているため、「#以外の任意の文字から始まる行」のみが抜き出されます。なお、空行は抜き出されません。その結果、ファイル中で#以外の文字から始まるHello Worldの行のみが抜き出され、それが表示されるという仕組みです。

なお、「grep ^[^#]」というコマンドをシェル上で実行する際には、特殊記号がシェルによって解釈されるのを防ぐため、「grep '^[^#]'」のように正規表現をシングルクォートで囲む必要がありますが、この例の場合は逆にシングルクォートを付けてはいけません。それは、「#!」の右側に記述したgrepコマンドは、シェルによってではなく、カーネルによって直接解釈されるためです。

リスト6 grepコマンドを使う方法(sh_grep)

#!/bin/grep ^[^#]           ← grepコマンドを使ったスクリプト
                            ← ここは空行(スペースもなし)
Hello World                 ← ファイルにメッセージを直接記述