意外に知らない人が多いシェルスクリプトについて、基本的な部分の解説。主に初心者をターゲットとした内容。
当ページ 管理人のネット上・実社会での観測結果によると、「シェルスクリプト」を「シェル」と呼ぶ人のスキルは著しく低い傾向がある。
同感である。
#!/bin/bashecho "Hello World !"exit 0
先頭に指定した #!
で始まる「シバンこれは決まり文句のようなものなので、必ず 1 行目に指定すること。
さっそく helloworld.sh を実行してみる。シェルスクリプトを実行する方法は大きく分けて 2 つある。
- bash コマンドに実行するシェルスクリプトのファイルを指定する。e.g.
$ bash helloworld.sh
- シェルスクリプトのファイルをコマンドとして直接実行する。e.g.
$ ./helloworld.sh
シェルスクリプトを (ls や cat のように) コマンドとして直接実行するためには、主に以下の 2 つの条件が必要。
$ var = "hoge"bash: var: コマンドが見つかりません
これはシェルが変数 var を「スペースがあることによって var コマンドと判断」し、それを実行しようとしたために起きたエラーである。そのため、変数に値を設定するには、=
の前後にスペースがあってはいけないのだ。
- シェルスクリプトはすべてコマンドの羅列である
- シンタックスエラーではなくコマンドエラーとして考える
- シェルスクリプトはコマンドライン・テンプレートである
- 最終的にどのようなコマンドが実行されるかイメージする
1、2 に関しては前述のとおり。3、4 を理解できるようになると、初心者レベルを脱却できるはずだ。シェルスクリプトはコマンドラインのテンプレートして捉え、最終的にどのようなコマンドが実行されるかをイメージして作成するとレベルアップの近道になるはずだ。
# シャープから行末はコメントになります。# if文の使用例if [ 0 -eq 0 ]; then echo "equal."fi
条件式には [
コマンドを使用します。これは if と同様に文法の一部ではなく /bin/[
というコマンドである。したがって [
の前後は必ずスペースが必要になる。それに続いている 0
や -eq
もパラメータであるため、区切りとしてスペースが必要になる。if 文での複数分岐も可能。
# read コマンドでキーボードから入力した文字列を、変数 str に設定するread str# 変数は必ず "" で囲んで使用する (変数に値が入っていない場合、"" がないと文法エラーになるため)if [ "$str" = "hoge" ]; then echo "hoge"elif [ "$str" = "fuga" ]; then echo "fuga"else echo "unknown"fi
elif
を増やして更に分岐を加えることも可能であるが、そういった場合は次の case 文を使用した方がよいだろう。
# 各分岐の最後の ;; を忘れずにcase "$str" in "hoge" ) echo "hoge" echo "hoge" ;; "fuga" ) echo "" ;; * ) echo "unknown" ;;esac
パターンの部分に正規表現は使用できないが、代わりにワイルドカード (すべての文字列と一致の「*
」と、任意の一文字と一致の「?
」) が使用可能。
次はループ処理を行う for 文。動作的には他の言語にある foreach 文と同様である。
# in に続く文字が次々に変数 i に代入されるfor i in 0 1 2 3do echo $idone
while 文のループ継続条件式には、if 文と同様に [
コマンドを使用可能である。
while [ "$str" = "" ]do read strdone
無限ループにするには :
コマンド(ヌルコマンド)を指定する。:
コマンドは一切の処理を行わずに、ただ正常終了するだけのコマンドである。
while :do read str if [ "$str" = "end" ]; then # break コマンドでループを抜ける break fidone
このように while 文や if 文の条件式部分には、[
コマンド以外の任意のコマンドが指定可能である。それは while 文や if 文が見ているのは条件式自体ではなく、「終了ステータス」というコマンドの実行結果を表す数値だからである。
# hogefile の中に文字列 hoge があるか?if grep 'hoge' hogefile >/dev/null 2>&1 echo "hoge found."fi
>/dev/null 2>&1
を指定すると、コマンドの実行結果やエラーなどの出力をディスプレイに一切表示しないようになる (ちなみに grep コマンドの -sq オプションでも同様の効果を得られる)。>/dev/null
と 2>&1
は逆にしてはいけない。必ずこの順番で指定すること。
ちなみに「1」は標準出力、「2」はエラー出力を意味している。要するに >/dev/null 2>&1
は、「2 (エラー出力)」を「1 (標準出力)」にまとめて、さらに出力先を「/dev/null (ごみ箱)」に変更する、という意味になる。
「終了ステータス」は、コマンド実行終了後に変数 $?
へ自動的に設定されている。通常、コマンド実行成功の場合は「0」、コマンド実行失敗は「0 以外」となる。$ touch hoge$ ls hogehoge$ echo $?0
直前に hoge ファイルを作成しているので、当然 ls コマンドは成功し、終了ステータスは 0 になる。$ rm hoge$ ls hogels: hoge: No such file or directory$ echo $?2
今度は hoge ファイルが存在しないため、ls コマンドの終了ステータスは 2 (0 以外)となっている。