LPIC-1 - 102試験 - 105:シェル、スクリプト、およびデータ管理 - 105.2 簡単なスクリプトをカスタマイズまたは作成する

Last Update : September 18 2014 21:34:21

     

a. シェルスクリプトの基礎

コマンドによる作業を自動化するには、その作業に必要なコマンドを記述したテキストファイルを作成し、コマンド名として、そのファイル名を指定することにより、ファイル中のコマンドを実行することが出来ます。このテキストファイルを「シェルスクリプト」といいます。
シエルスクリプトに記述できる内容はコマンドラインで受け付けられるものならば何でも書くことができます。

シェル変数とは値を格納する領域のことで、これを使うことにより、より高度なシェルスクリプトを作ることが出来ます。 シェル変数には次の3種類があります。

  • ユーザ定義変数
    ユーザが必要に応じて作成できる変数で、自由に名前を付けることが出来ますし、値の参照・設定も自由に行うことが出来ます。
    ユーザ定義変数の名前は先頭1文字が英字で、2文字目以降は英数字の組み合わせです。なお、_(アンダライン)は英字に含みます。
  • 位置パラメータ
    シェルが用意する変数で、名前は0〜nまでの数字と決まっています。シェルスクリプト実行時に指定した引数の値を持っています。
  • 環境変数
    シェルやアプリケーションソフトにより作成される変数で、名前は大文字のものがほとんどです。どのような環境変数があるかは「環境変数」をご覧ください。

1. スクリプトに渡す引数

シェルスクリプトでは、コマンドと同じように引数を指定できます。引数で指定した値はシェルスクリプト中では位置パラメータとして受け取ります。位置パラメータは、0~nの数字で表し、$n 又は ${n} の形式で値を参照します。

● 位置パラメータと関連する特殊パラメータ
 $0位置パラメータの最初のものですが引数の値ではなく、コマンド名または、シェルスクリプト名(パス名)を値として持っています。
 $#引数の数を値として持っています。
 $*全ての引数を空白で区切り、まとめて1つの文字列とした値を持っています。
 $@全ての引数を個別の値として持っています。

$ set PARA1 PARA2 PARA3 PARA4 <--- 位置パラメータ1~4に値をセットします $ echo $0 <--- 位置パラメータ0の値を表示します /bin/bash <--- コマンド名(bash)です $ echo $1 <--- 位置パラメータ1の値を表示します PARA1 $ echo $2 PARA2 $ echo $3 PARA3 $ echo $4 PARA4 $ echo $# <--- 値が設定されている位置パラメータの数を表示します 4 $ echo $* PARA1 PARA2 PARA3 PARA4 <--- 全ての位置パラメータの値です $ echo $@ PARA1 PARA2 PARA3 PARA4 <--- 全ての位置パラメータの値です $ set "$*" <--- set "$1 $2 $3 $4"と同じです $ echo $1 PARA1 PARA2 PARA3 PARA4 <--- 位置パラメータ1に全ての位置パラメータの値が設定されています $ set PARA1 PARA2 PARA3 PARA4 $ set "$@" <--- set "$1" "$2" "$3" "$4"と同じです $ echo $1 PARA1 <--- 位置パラメータ1には"$1"の値が設定されています $ echo $2 PARA2

2. 実行結果の戻り値

シェル上でlinuxコマンドを入力すると、終了時にシェルに対して戻り値が返されます。この戻り値はコマンドが正常に終了したかどうかを表しています。

 正常終了した場合の戻り値 : 0
 異常終了した場合の戻り値 : 0以外

 この戻り値は変数「$?」に格納されます。


$ ls file1.txt file1.txt $ echo $? <--- 戻り値を表示します 0 $ ls file1.txt <--- 存在しないファイルを指定 ls: cannot access file2.txt: そのようなファイルやディレクトリはありません $ echo $? 2 $ lt file1.txt <--- 存在しないコマンドを指定 -bash: lt: コマンドが見つかりません $ echo $? 127


b. ファイルのチェック

1. ifによる条件分岐

ifコマンドには2つの形式があります。条件が2つの場合(真か偽か)は形式1を使い、複数のときは形式2を使います。また、条件不成立時に実行するコマンドが無い場合はelse以下を省略できます。(fiは必要です)

● 形式1
if 条件 then  <--- ifとthenを1行で記述するときは;(セミコロン)で区切ります(if 条件 ; then) コマンドリスト  <--- 条件成立時に実行するコマンドを指定します else コマンドリスト  <--- 条件不成立時に実行するコマンドを指定します fi  <--- ifコマンドの最後を表します

● 形式2
if 条件 then  <--- ifとthenを1行で記述するときは;(セミコロン)で区切ります(if 条件 ; then) コマンドリスト  <--- 条件成立時に実行するコマンドを指定します elif 条件  <--- else ifの意味です。elifに対するfiはありません コマンドリスト  <--- 条件不成立時に実行するコマンドを指定します then コマンドリスト elif 条件  <--- else ifは複数の指定ができます then コマンドリスト else コマンドリスト  <--- else if条件不成立時に実行するコマンドを指定します fi  


2. case文による分岐

caseコマンドは複数の条件により処理を振り分けます。ifコマンドと似ていますが、条件が多いときにはifコマンドより処理を分りやすく記述できます。 「式」の値と一致するパターンの所のコマンドを実行します。コマンドリストの最後にはセミコロンを2個指定します。パターンにはワイルドカード(*、?、[ ]、等)が指定できますし、複数のパターンを|(縦線)で区切って指定できます。

case 式 in  <--- 式には変数や位置パラメータを指定できます パターン1) コマンドリスト;;  <--- コマンドリストの最後は;;(セミコロン2個)です パターン2) コマンドリスト;; ・・・ パターンn) コマンドリスト;; esac  <--- caseコマンドの最後を表します

複数のパターンを指定した例を示します。変数nameの値がMまたはmの場合は「Merry」を、Kまたはkの場合は「Ken」を、それ以外の場合は「?」を表示します。
case $name in "M" | "m" ) echo "Merry";; "K" | "k" ) echo "Ken";; * ) echo "?";; esac


3. for文による繰り返し処理

forコマンドは先頭で変数に値を設定しつつ繰り返します。設定する値が無くなったら繰り返しを終了します。 変数には形式1の場合はin以降で指定した値が、形式2の場合は位置パラメータの値が設定されます。

● 形式1
for 変数 in 値1 値2 … 値n  <--- 変数に値1から値nを設定しつつ繰り返します do コマンドリスト done

● 形式2
for 変数  <--- 変数に位置パラメータの値を設定しつつ繰り返します do コマンドリスト done


4. while文またはuntil文による繰り返し処理

whileコマンドとuntilコマンドは繰り返しを制御します。whileコマンドは条件が成立(真)の間繰り返します。それに対して、untilコマンドは条件が不成立(偽)の間繰り返します。これらのコマンドで繰り返しの処理をする場合は、次のことに注意する必要があります。 whileコマンドの場合は、繰り返しに入る前に条件が真になるような処理を行わないと、繰り返しを行わないで直ちに繰り返しを抜けてしまいます。 untilコマンドの場合は、繰り返しに入る前に条件が偽になるような処理を行わないと、繰り返しを行わないで直ちに繰り返しを抜けてしまいます。 繰り返しの中で何らかの手段で条件を変えないと、永久ループになってしまいます。

● whileコマンド
while 条件 do コマンドリスト  <--- 条件を偽に変えるようなコマンドが必要です done

● untilコマンド
until 条件 do コマンドリスト  <--- 条件を真に変えるようなコマンドが必要です done


5. testコマンド

if 文など条件式を評価する場合には test コマンドを使用する。どのような評価を行うかはオプションにより細かく指定することが可能である。 test コマンドは評価結果に従い、真(0)か偽(1)かの終了ステータスを返すのみで、画面上へのメッセージ出力等は一切行わない条件評価に特化したコマンドである。 testコマンドは、条件によって処理の流れを分岐させたいときなどに使用します。 以下に比較文を書く際の形式について紹介します。

● ファイル形式のチェック
 -b ファイル名指定したファイルがブロックデバイスファイルなら真である
 -c ファイル名指定したファイルがキャラクタデバイスファイルなら真である
 -d ファイル名指定したファイルがディレクトリなら真である
 -f ファイル名指定したファイルが通常ファイルなら真である
 -L ファイル名指定したファイルがシンボリックリンクなら真である
 -p ファイル名指定したファイルが名前付きパイプなら真である
 -S ファイル名指定したファイルがソケットなら真である

● ファイルパーミッションのチェック
 -g ファイル名指定したファイルにSGIDがセットされていれば真である
 -k ファイル名指定したファイルにスティッキービットがセットされていれば真である
 -r ファイル名指定したファイルが読み取り可能なら真である
 -u ファイル名指定したファイルにSUIDがセットされていれば真である
 -w ファイル名指定したファイルが書き込み可能なら真である
 -x ファイル名指定したファイルが実行可能なら真である

● その他のファイルのチェック
 -e ファイル名指定したファイルが存在すれば真である
 -s ファイル名指定したファイルのファイルサイズが0より大きければ真である

● 文字列のチェック
 -n 文字列文字列の長さが0より大きければ真である
 -z 文字列文字列の長さが0であれば真である
 文字列1 = 文字列22つの文字列が等しければ真である
 文字列1 != 文字列22つの文字列が等しくなければ真である

● 数値のチェック
 数値1 -eq 数値22つの数値が等しければ真である
 数値1 -ge 数値2数値1が数値2以上であれば真である
 数値1 -gt 数値2数値1が数値2より大きいのであれば真である
 数値1 -le 数値2数値1が数値2以下であれば真である
 数値1 -lt 数値2数値1が数値2未満であれば真である
 数値1 -ne 数値22つの数値が等しくなければ真である

● 論理結合
 !条件条件が偽であれば真である
 条件1 -a 条件2条件1と条件2の両方が真であれば真である
 条件1 -o 条件2条件1と条件2のどちらかが真であれば真である

test コマンドは与えられた2つの数値を比較し、それらの等価・大小を評価することができる。 比較条件は実行時に指定されたオプションにより決定される。 各 test コマンドの終了ステータスを echo コマンドで確認してみる。 なお、echo コマンドはセミコロンを使用し、test コマンド実行後に連続実行している。


6. seq コマンド

一定の割合で徐々に増加 (減少) する数値列を表示するには、seq コマンドを使用します。

● seq コマンド構文
  seq [オプション] [開始値] [増分] [終了値]

増分を省略すると1ずつになる。

1から10まで1ずつ増加する数値を表示
$ seq 1 1 10 1 2 3 4 5 6 7 8 9 10

1から10まで1ずつ増加する数値の加算合計を表示
$ vi test1
#!/bin/bash j=0 for i in `seq 1 10` do j=$(($j+$i)) done echo $j
$ source test1 55


7. read コマンド

read コマンドは、標準入力から入力を受け付けて結果を引数の変数(変数名で指定)に代入することができます。
read コマンドを実行すると、キーボードからの入力待ち状態になり、オプションを指定しなければ、Enter キーが入力されるまでの値が指定した変数に設定されます。 データを読み取る以外にも、入力待ち状態になることを利用して、シェルスクリプトの処理を一時的に止める、といった使い方もできます。

● read コマンド構文
  read [オプション] [変数名]

● read コマンドオプション
 -t num入力の確定をnum秒だけ待つ(例:read -t 10 hensuu)
 -p prompt入力を促す文字列promptをプロンプトとして出力する
 -n num標準入力から指定の文字数を読み込むとプロンプトを出力
 -a変数を配列として配列変数に値をセットする
 -r入力時のバック・スラッシュをエスケープ文字とみなさない

キーボードからの入力を変数 ANSWER に代入
$ read ANSWER hello <--- helloをキーボードから入力
$ echo $ANSWER hello

キーボードからの入力を複数の変数ANS1 ANS2 ANS3 に代入
$ read ANS1 ANS2 hello Thanks goodby <--- hello Thanks goodbyをキーボードから入力
$ echo $ANS1 hello
$ echo $ANS2 Thanks goodby <--- 1つ目のスペースで区切られた残りが入っている
$ read ANS1 ANS2 ANS3 hello Thanks goodby <--- hello Thanks goodbyをキーボードから入力
$ echo $ANS1 hello
$ echo $ANS2 Thanks
$ echo $ANS3 goodby

キーボードからの入力を配列変数 ANS に代入
$ read -a ANS hello Thanks goodby <--- hello Thanks goodbyをキーボードから入力
$ echo ${ANS[0]} <--- 配列1つ目を表示 hello
$ echo ${ANS[1]} Thanks
$ echo ${ANS[2]} goodby
$ echo ${ANS[@]} <--- 配列の全てを表示 hello Thanks goodby



c. シェルスクリプトの実行環境

どのスクリプトも1行目に 「#!/bin/bash」のような記述がありますが、この記述は、shebang(シェバング)と呼ばれるもので、「ここで指定したプログラム(bash)を利用して以下の内容を実行してください」という意味です。
ここの記述を変えれば、別のシェルで実行することができます

スクリプトファイルを実行するには、source コマンドを使います。この場合、スクリプトファイルのパーミッションは読み取り権があれば実行可能です。ただし、そのスクリプトファイルの存在するディレクトリには、実行権が必要です。
source コマンドは「.」でも代用できます。
シェルスクリプトでは、実行したユーザーの権限で処理されます。

シェルスクリプトを通常のコマンドと同じように実行するには、ファイルのパーミッションに実行権を与えます。 また、環境変数PATHにコマンドサーチパスの設定をしておけば、ファイル名の指定だけで実行できます。PATHに設定していない場合はパス名とともに指定します。

$ source test1 55
$ . test1 55
$ chmod 755 test1 $ ls -al test1 -rwxr-xr-x 1 root root 55 4月 22 18:10 2013 test1
$ ./test1 55

z. 出題範囲概要

●主要な知識範囲
標準的なshの書式(ループ、テスト)を使用する
コマンド置換を使用する
コマンドによって返される、成功または失敗を示す戻り値やその他の情報をテストする
条件に応じて、スーパーユーザにメールを送信する
先頭行(#!)を利用して、適切なスクリプトインタプリタを選択する
スクリプトの位置、所有権、実行権、SUID権を管理する
●重要なファイル、用語、ユーティリティ
for, while, test, if, read, seq


  [ 例題 ] 
  1. 102:105.2 問01  シェルスクリプトで条件チェックを行うコマンド
  2. 102:105.2 問02  testコマンド
  3. 102:105.2 問03  シェルスクリプト
  4. 102:105.2 問04  シェルスクリプト
  5. 102:105.2 問05  実行可能に変更するために使用するコマンド
  6. 102:105.2 問06  シェル環境で実行可能な関数


     

www.it-shikaku.jp