目次  I Love CUI

シェルスクリプトとは

プログラム言語としてシェルスクリプトを見た場合、古くさい感じがします。変数の使い方や制御文の文法は変だし、局所変数も使えません。数値の計算さえ十分にはできません。しかし、シェルスクリプトの真価はそんなところにはないのです。

シェルスクリプトの真価は、コマンドラインで実行するコマンドをバッチ処理する際に発揮されます。コマンドラインで実行したコマンドの実行や、リダイレクト、パイプラインといった操作が、そのまま記述できます。つまり、コマンドラインでテストしたプログラムを、そのままスクリプトファイルとして記録し、実行できるのです。バッチ処理のためのプログラム言語としては、シェルスクリプトは今でも現役です。

そこで、シェルスクリプトを活用するためのポイントをまとめてみました。

入出力

シェルスクリプトが扱うのは原則として文字列であると考えたほうがいいでしょう。数値も扱えますが、文字列から数値として変換されないと利用できません。

出力

シェルコマンドで文字列を出力するのは echo コマンドです。echo は空白で区切られた文字列の引数を標準出力に出力します。引用符で囲まれた部分は、囲まれた部分の文字列のみを出力します。

~/markdown/simple$ echo foo bar baz
foo bar baz
~/markdown/simple$ echo "hello, world"
hello, world

echo にワイルドカードが引数として渡された場合、展開されて渡されます。

~/markdown/simple$ echo *.md
example.md index.md makingtool.md markdown.md pattern_match.md   
shell_script.md simple.md tag_example.md template.md

ワイルドカードそのものを出力したいときは、ワイルドカードを引用符で囲みます。

~/markdown/simple$ echo "*"
*

変数

変数にも原則的には文字列が納められます。変数への代入は = を用いますが、変数や値との間にスペースを置けません。変数に納められた文字列を利用するときは $ をつけて、$foo の様に使います。また、$foo は文字列ですから、他の文字列と密接させるとそれらが一つの文字列の引数とみなされます。しかし、間にスペースを挟むと、2つの別々の引数とみなされます。

~/markdown/simple$ foo=hello
~/markdown/simple$ echo $foo
hello
~/markdown/simple$ echo $foo", world"
hello, world
~/markdown/simple$ echo $foo ", world"
hello , world

入力

コマンドラインからの入力

コマンドラインからの入力を変数に納めるには read コマンドを使います。つまり、コマンドラインから変数への入力は read 変数 で行います。

~$ cat foo
read name
echo $name
~$ bash foo
John
John

read コマンドに -p オプションをつけると入力時にプロンプトを表示できます。

~$ cat foo
read -p "name: " name
echo $name
~$ bash foo
name: Dolly
Dolly

コマンドラインの引数の処理

シェルスクリプトへはコマンドラインからの引数が渡せなければ不便です。シェルスクリプトへコマンドライン引数を渡すときは、特殊な組み込み変数を利用します。

コマンドラインからシェルスクリプトへ渡されるコマンドライン引数は位置パラメータという特殊な変数にセットされます。位置パラメータは 1, 2, ... , 9 の変数で、コマンドライン引数を表します。したがって、$1 は第1引数、$2 は第2引数、... の文字列になります。次のシェルスクリプト foo では、位置パラメータのテストをしています。

~/markdown/simple$ cat foo
echo $1
echo $2
echo $3

foo スクリプトを実行するためには bash コマンドの引数として foo を与えます。また、foo スクリプトに続けて foo bar baz という3つの文字列を引数として渡します。

~/markdown/simple$ bash foo bar baz foobar
bar
baz
foobar

@ 変数にはすべてのコマンドライン引数のリストが代入されます。これらば、for in コマンドで1つずつ取り出すことができます。

~/markdown/simple$ cat foo
for arg in "$@"; do
  echo $arg
done

テストしてみましょう。

~/markdown/simple$ bash foo bar baz
bar
baz

# 変数にはコマンドライン引数のリストが代入されます。コマンドライン引数の数がシェルスクリプトの要求する引数の数とマッチしているかどうかのチェックに使われます。

~/markdown/simple$ cat foo
if [ $# != 1 ]; then
  echo "mismatch in the number of args" 1>&2
  exit 1
fi

echo "the arg is $1"

これを bash で実行すると引数の数が1以外ではエラーになります。

~/markdown/simple$ bash foo bar baz
mismatch in the number of args
~/markdown/simple$ bash foo bar
the arg is bar

位置パラメータと @, # の組み込み変数を使えば、自由にコマンドライン引数の活用ができます。

シバン (shebang)

シェルスクリプトはテキストファイルですが、次の手順でシェルコマンドとして使うことができます。

シバンとは #(hash)-!(bang) の略称でテキストファイルの冒頭に次のようにそのファイルを引数にするコマンドの位置を登録することです。

#! /bin/bash

echo "hello, world"

このソースコードが foo というテキストファイルに書かれているとします。普通はこのファイルを bash コマンドの引数として与えるとスクリプトの中のシェルコマンドが実行されます。

しかし、それに加えてこのファイルのパーミッションを chmod +x foo として実行可能ファイルにします。すると、./foo のようにシェルスクリプトをシェルの外部コマンドとして実行することができます。

~/markdown/simple$ chmod +x foo
~/markdown/simple$ ./foo
hello, world

さらに、cp foo ~/bin/foo としてコマンドサーチパスの通ったディレクトリにコピーすれば、ディレクトリのどこからでも foo コマンドが実行できます。

まとめ

以上が、シェルスクリプトを自作のコマンドとして作るためのコツです。シェルスクリプトのプログラム言語としての文法については、ネットの記事や成書を参考にしてください。

戻る