ShellScript

ShellScript 基礎知識

ShellScript 基礎知識

大学のサークルの勉強会のために, ShellScriptの知識的ものをまとめたものです.
( 『[改訂新版] シェルスクリプト 基本リファレンス #!/bin/shで、ここまでできる 』を参考にしました )

ShellScriptとは?

シェル(Shell)
Unixにログインして最初に起動するプログラム
スクリプト(Script)
簡易的なプログラム. 機械語への翻訳を必要とせずに実行できる
ShellScript
コマンドをファイルにまとめたもの. 単純なコマンドの実行に加えてfor文やif文などによるループや条件判断やシェル変数に値を代入/参照したりできる. (もちろん, シェルに直接ifなどを書くこともできる)

Shellの話

元々のUnix標準シェルは sh ( a.k.a. Bourne Shell )
この sh がシェルスクリプトを記述するための標準シェル.

低機能な sh にヒストリ機能, ジョブコントロール機能などを追加し, C言語風な文法に改変したのが csh などの Cシェル系
cshは多くの人に使われたが, shと文法が異なっていたり, シェル関数が使えないなどの問題があった.

その後, shの上位互換性を保ちながら, cshの機能を取り入れ, ファイル名保管機能などを追加したbash(Bourne-Again Shell)が登場(Bシェル系). (Bシェル系はCシェル系の登場前から存在はしていた)

現在では, Linuxの標準シェルとしてbashが採用され, 多くのユーザーがbash系のShellを利用している.

様々なShell

bash
みんな大好き! bash
ash
bashのようにshにはないような機能拡張はせずに, shに近い実装を行ったShell. dashという名前でDebian系のLinuxにインストールされている
ksh
Solarisに標準で付属しているShell. sh を拡張したBシェル系
zsh
Bシェル系とCシェル系の両方の特徴を取り入れ, 大幅に機能を拡張したShell.

Let's Try

自分のログインシェルを調べてみる

$ echo $SHELL  # シェル変数の値を表示

ShellScriptの特徴

  • 実行ファイルはテキストファイル (コンパイル不要, インタラクティブ言語)
  • 異なるOSでもそのまま動作.
  • 実行速度は遅い
  • 既存のコマンドを組み合わせて一定の動作を行わせるのに適している

ShellScriptを実行してみる

HelloWorld

#!/bin/sh

echo 'Hello World'

#!/bin/sh : 1行目の先頭から, #!に続いてシェルの絶対パスを記述
echo '...' : echoコマンドで任意の文字列を表示

ファイルの作成&実行

$ vi hello  # TextEditorでhelloファイルを作成&編集
$ chmod +x hello  # ファイルに実行属性をつける
$ ./hello # シェルスクリプトを実行
Hello World

#!/bin/shの意味

1行目に#!/bin/shと書くことによって, シェルスクリプト実行時に, システム内部で /bin/sh ShellScriptName というコマンドが実行される
(helloというファイル名のシェルスクリプト ... /bin/sh ./hello が実行される)
/bin/shはファイルの中身を1行ずつ実行. この際1行目は行頭に#があるため, コメントとして解釈される

となると..

#!bin/sh の部分を自由なコマンドに変えることができる.
例えば #!/usr/bin/perl とかけば, Perlスクリプトになる.
またスクリプトだけでなく, 普通のコマンドを書くこともできる.
(#!のところに書いたコマンドが、スクリプトのファイル名を引数につけて実行されるだけ)

ShellScriptのフォーマット

改行とセミコロン

改行でリストの終端. セミコロンも同じ意味を持つ.

Sample

pwd
cd Desktop

pwd; cd Desktop

は同じ意味

コメント

コメントは #

終了ステータス

コマンドは終了ステータスをreturnする.
終了ステータスが0ならば真, 0以外ならば偽

この終了ステータスに応じて, 条件分岐などを行える
(コマンドが正常に実行できたら, ifの中身を実行するなど)

(注) 0でtrueな点に注意
C言語のretunを想像するとわかりやすい. return 0 で正常終了なのでコマンドの終了ステータスも0で正常終了

Sample

$ true  # trueコマンドを実行
$ echo $? # 特殊パラメータ$?の中に, 終了ステータスが格納されている

用語と循環構造

用語

単純コマンド
lsやcpなどのよく使うコマンド.
複合コマンド
if文やfor文などの構文や()で囲んだサブシェルなど. 全体が一つのコマンド.
パイプライン
1つ以上のコマンドがパイプ(|)でつながったもの.
リスト
1つ以上のパイプラインがセミコロンまたは改行でつながったもの. if分のifやthenの直後に記述するのはリスト.

循環構造

コマンド -> コマンドをつなげたパイプライン -> 1つ以上のパイプラインがつながったリスト -> リストを複合コマンドに利用 -> 複合コマンドも一つのコマンド

のように, これらのシェル文法は循環する

文法

単純コマンド

書式

コマンド名 [引数 ...]

ls -l # カレントディレクトリのファイルのリストを表示
echo 'Hello World'  # メッセージの表示
pwd # カレントディレクトリ名

単純コマンドのリダイレクト

コマンドの標準出力を別なコマンドの入力にしたり, ファイルに書き出したりできる

date > timestamp.txt  # dateコマンドの出力結果をファイルに書き込み

複合コマンド

if文やfor文などの構文もそれ全体が1つのコマンド.

while :; do
  echo 'Hello World'
done

複合コマンドのリダイレクト

複合コマンドは全体が1つのコマンドなので, 単純コマンドと同じようにこの標準出力をファイル等にリダイレクトをすることができる

for n in 1 2 3 4 5
do
  echo 'Hello World'
done > newFile  # forの標準出力をnewFileというファイルに書き込む

参考文献