POSIX シェルスクリプト ハンドブック
POSIXシェルスクリプトとは
編集POSIXとは
編集POSIX(Portable Operating System Interface)は、UNIX系オペレーティングシステムでの互換性を保つための標準規格です。POSIXに準拠することで、異なる環境間でシェルスクリプトを移植可能にすることができ、さまざまなOSやシェルで動作するスクリプトを書くことが容易になります。
シェルスクリプトは、シェルと呼ばれるプログラムを通じてコマンドを実行するためのスクリプト言語です。シェルにはさまざまな種類がありますが、POSIXシェルスクリプトはsh
(Bourne Shell)の仕様に基づき、UNIX系OSのほとんどで動作します。
シェルの種類
編集シェルには複数の種類があり、それぞれに独自の機能や構文拡張が存在します。以下は主なシェルの例です。
- Bourne Shell (sh): POSIX標準に準拠したシェルで、多くのUNIX系OSで基本的なシェルとして使用されます。
- Bash (Bourne Again Shell): GNUプロジェクトの一環として開発され、Linuxディストリビューションでデフォルトのシェルとなっていることが多いです。BashはPOSIX互換のスクリプトをサポートしながら、多くの拡張機能も提供します。
- Korn Shell (ksh): POSIX準拠のシェルであり、
sh
よりも高機能な環境を提供します。UNIX環境では広く使われていました。 - Zsh: 拡張機能が豊富で、Bashやkshよりも多機能なシェルです。ZshもPOSIX準拠の部分が多くありますが、特定の機能はPOSIX非互換です。
POSIX準拠の利点
編集POSIXに準拠したシェルスクリプトを書くことで、異なるシステム間の移植性が向上します。たとえば、Linux、FreeBSD、macOS、さらには一部のWindows環境でも同じスクリプトを問題なく実行できる可能性が高くなります。また、POSIXシェルスクリプトは軽量で効率的なため、システム管理タスクの自動化や小規模なユーティリティの作成に適しています。
シェルスクリプトの基本
編集はじめてのスクリプト
編集シェルスクリプトはテキストファイルとして保存され、シェルによって実行されます。最初のスクリプトとして、簡単な「Hello, World!」プログラムを作成してみましょう。
#!/bin/sh echo "Hello, World!"
スクリプトファイルの作成
編集スクリプトファイルを作成するには、任意のテキストエディタ(vi
, emacs
など)を使用します。たとえば、hello.sh
という名前のファイルを作成し、上記の内容を記述します。
実行権限を設定する
編集シェルスクリプトを実行する前に、ファイルに実行権限を付与する必要があります。chmod
コマンドを使って実行権限を設定します。
chmod +x hello.sh
スクリプトを実行する
編集スクリプトを実行するには、次のコマンドを使用します。
./hello.sh
正しく設定されていれば、「Hello, World!」と表示されます。
Shebang (#!/bin/sh
)
編集
シェルスクリプトの1行目にある#!/bin/sh
は「シバン(Shebang)」と呼ばれ、どのシェルでスクリプトを実行するかを指定するものです。/bin/sh
はPOSIX準拠のシェルであり、これを指定することでスクリプトの互換性が確保されます。システムによっては、異なるシェル(例: /bin/bash
)を使用する場合もありますが、POSIX互換を維持するために/bin/sh
を使用するのが一般的です。
コメントの使用
編集シェルスクリプト内でコメントを使用して、コードの説明やメモを記述することができます。コメントは#
で始め、行末までがコメントとして扱われます。
#!/bin/sh # これはコメントです echo "これは実行されます" # echo "これは実行されません"
コメントはスクリプトの可読性を高め、後からスクリプトを読み返す際に役立ちます。
シェルスクリプトの構文と構造
編集変数
編集シェルスクリプトでは、変数を使ってデータを一時的に保存し、後で使用することができます。変数の定義は非常にシンプルで、=
記号を使って値を代入します。以下は基本的な変数の使い方です。
変数の定義
編集シェルでは、変数を定義するときに=
の前後にスペースを入れてはいけません。スペースを入れると、エラーが発生します。
#!/bin/sh name="Joe"
このスクリプトでは、name
という変数に「Joe」という文字列を代入しています。
変数の参照
編集変数を使用するには、変数名の前に$
を付けます。
#!/bin/sh name="Tom" echo "Hello, $name!"
このスクリプトを実行すると、Hello, Tom!
が出力されます。
環境変数
編集環境変数はシステム全体で利用できる変数です。例えば、PATH
やHOME
といった変数はよく使われます。環境変数はexport
コマンドを使って設定することができます。
#!/bin/sh export MY_VAR="This is an environment variable"
export
を使わない変数は、スクリプトの中でのみ有効です。
定数(読み取り専用変数)
編集シェルスクリプトでは、readonly
コマンドを使って変数を定数にすることができます。定数は再代入ができません。
#!/bin/sh readonly my_const="Cannot change this"
このスクリプトでmy_const
を後から変更しようとするとエラーになります。
コマンド置換
編集コマンド置換は、シェルコマンドの結果を変数や他のコマンドに渡す際に便利です。コマンドの結果を変数に代入するには、バッククォート(`command`
)や
$(command)を使います。
バッククォートを使ったコマンド置換
編集#!/bin/sh current_time=`date` echo "The current time is: $current_time"
$()構文を使ったコマンド置換
編集$(command)
を使う方が一般的です。バッククォートに比べてネストがしやすく、読みやすさも向上します。
#!/bin/sh current_time=$(date) echo "The current time is: $current_time"
このようにして、date
コマンドの結果を変数に代入し、その結果を出力します。
算術演算
編集POSIXシェルでは、基本的な整数の算術演算がサポートされています。演算を行うには、$((expression))
の形式を使います。
#!/bin/sh num1=10 num2=20 sum=$((num1 + num2)) echo "Sum is: $sum"
基本的な演算子
編集+
足し算-
引き算*
掛け算/
割り算%
余り
POSIXシェルでは、小数点以下の演算はサポートされていないため、整数のみを扱います。
制御構文
編集シェルスクリプトでは、条件分岐やループを使って柔軟な動作を実現できます。
条件分岐 (if
文)
編集
if
文を使って条件に応じた処理を行うことができます。基本的なif
構文は以下の通りです。
#!/bin/sh if [ 条件 ]; then コマンド fi
if
, then
, else
, elif
編集
if
文にelse
やelif
(else ifの略)を追加することで、複数の条件に対応できます。
#!/bin/sh num=10 if [ $num -gt 10 ]; then echo "num is greater than 10" elif [ $num -eq 10 ]; then echo "num is equal to 10" else echo "num is less than 10" fi
条件式と演算子
編集シェルスクリプトでは、条件式に使える演算子がいくつかあります。以下は主な比較演算子です。
数値の比較:
編集-eq
: 等しい-ne
: 等しくない-lt
: より小さい-le
: 以下-gt
: より大きい-ge
: 以上
文字列の比較:
編集=
: 等しい!=
: 等しくない-n STRING
: 文字列が空でない-z STRING
: 文字列が空
ファイルのテスト:
編集-e FILE
: ファイルが存在するか-f FILE
: 通常のファイルか-d FILE
: ディレクトリか-r FILE
: 読み取り可能か-w FILE
: 書き込み可能か-x FILE
: 実行可能か
#!/bin/sh file="example.txt" if [ -e $file ]; then echo "$file exists." else echo "$file does not exist." fi
ループ構文
編集繰り返し処理を行うために、シェルではfor
やwhile
などのループ構文を使います。
for
ループ
編集
for
ループはリストの中の各要素に対して繰り返し処理を行います。
#!/bin/sh for name in Alice Bob Carol David; do echo "Hello, $name!" done
この例では、リストにある4人の名前が順番に表示されます。男女の名前を均等に含めることで、ジェンダー平等にも配慮しています。
while
ループ
編集
while
ループは、条件が真である限り処理を繰り返します。
#!/bin/sh counter=1 while [ $counter -le 5 ]; do echo "Counter: $counter" counter=$((counter + 1)) done
このように、シェルスクリプトでは変数や制御構文を用いることで、柔軟で効率的なスクリプトを記述することができます。
関数
編集シェルスクリプトでは、関数を定義することでコードの再利用が可能になります。関数は以下のように定義します。
関数の定義と呼び出し
編集#!/bin/sh greet() { echo "Hello, $1!" } greet "Alice" greet "Bob"
この例では、greet
関数を定義し、引数として名前を受け取って挨拶を表示します。
関数の戻り値
編集関数からの戻り値は、通常は終了ステータスとして扱われます。成功した場合は0を返し、失敗した場合は1以上の値を返します。
#!/bin/sh add() { return $(($1 + $2)) } add 5 10 result=$? echo "The result is: $result"
このスクリプトでは、add
関数で足し算を行い、戻り値を取得して表示しています。
こちらが6章の内容です。
スクリプトの実行
編集シェルスクリプトを実行するには、いくつかの方法があります。
直接実行
編集スクリプトファイルを実行可能にした後、直接実行することができます。
chmod +x script.sh ./script.sh
シェルを指定して実行
編集シェルを明示的に指定してスクリプトを実行することも可能です。
sh script.sh
入力リダイレクション
編集スクリプトに入力をリダイレクトすることもできます。
./script.sh < input.txt
パラメータの受け取り
編集スクリプトに引数を渡すことができ、$1
, $2
, ...で参照できます。
#!/bin/sh echo "First argument: $1" echo "Second argument: $2"
このスクリプトを./script.sh arg1 arg2
のように実行すると、引数が表示されます。