シェルスクリプトの概要


シェルとは

シェルは入力されたコマンドのパスを見つけ出し、Linuxカーネルに実行するようにお願いしてくれます。要するにコマンドを解釈するものです。このことからシェルは別名コマンドインタープリターとも呼ばれます。
シェルはLinux特有のものではなく、windowsではファイルを管理するエクスプローラー(GUI)がシェルです。

Linuxカーネルとは

ハードウェアの抽象化やプロセス管理など、OSの核となる部分。
シェルとLinuxカーネルを分離することで、シェルが何かしらの原因で異常終了してもLixuxカーネルには影響を及ぼさないこと(このことからカーネルを守る殻”シェル”と名付けられる)や、シェルがコマンドのインターフェイスに徹することでユーザー好みにカスタマイズできるなどのメリットがあります。

シェルスクリプトとは

▪️簡単に説明
シェルが解釈できるコマンドライン(Unix系コマンドなど)を予め記述したファイルのこと。
ポイントとしては、シェルスクリプトは、DSL(Domain-Specific Language)であり、汎用プログラミング言語(Ruby,PHPなど)と違うためシェルスクリプトらしい書き方をする意識する必要がある。
また、慣習として拡張子を.shとするが、実際の動きは、拡張子があろうとなかろうと一緒。(linuxに拡張子という概念はないです)

▪️詳しく説明
複数のコマンドと条件分岐やループ処理等を使用し、一連の処理を実現するプログラムのことである。bash、zsh などのシェルを利用し、シェルによって解釈・実行されるスクリプトなので、シェルスクリプトと呼ばれる。

なぜシェルスクリプトを使うのか

  • 開発環境等のバックアップやメンテナンスをする際にいちいちコマンドを沢山打たなくて済む。要は作業を自動化することができ、属人性を排除することができる

最低限理解する必要のある単語

標準入出力 (標準入力、標準出力、標準エラー出力)

この概念は非常に大切なのでなぜ標準と呼ばれていのかもゆっくり理解した方がよいです。まず、標準入出力とは、下記3つの総称のことです。

  • 標準入力(stdin):プログラムの標準的な入力。通常ははキーボードが指定されているがファイルにすることも可能
  • 標準出力(stdout):プログラムの標準的な出力。通常は端末ディスプレイが指定されているが、ファイルやプリンタも可能
  • 標準エラー出力(stderr):プログラムのエラーメッセッジを主力するための標準的な出力。通常は端末ディスプレイが指定されているが、ファイルやプリンタも可能

要するに、標準入出力とは、キーボードやファイルなどを抽象化(標準化)したものです。抽象化することで各コマンドは標準入力から入力を受け取り、結果を標準出力に返すといった感じに、プリンターやファイル、キーボードなどを意識する必要がなくなります。

書き方

1行目で必ずシェルの種類を指定

example.sh
#!/bin/bash

" #! "は、Shebang(シェバン)と呼ばれ、コメントアウトではない。"#! bashの絶対バス"で、bashによって解釈、実行されることになる。
(Shebangは Hash(#) と Bang(!) をくっつけた HashBang の省略形)

シェルにzshを使っているのであれば下記のようになる

example.sh
#!/bin/zsh

実行時に引数を渡すことができる

もちろんbashで関数をかけますが、ファイル自体を関数のように扱うことができます。バッチ処理などで引数に日付や定数などを渡して実行したりすることが多いです。例えば、第一引数であれば、$1と書く事でその値を参照できます

\$0 : ファイル名
\$1 : 第一引数
\$2 : 第二引数

example.sh
#!/bin/bash

#引数の存在チェック

echo "$0"

if [ "$1" -gt "$2" ]
then
    echo "1番目の引数が2番目の引数より大きい"
elif [ "$1" -eq "$2" ]
then
    echo "1番目の引数と2番目の引数は同じです"
else
    echo "1番目の引数が2番目の引数より小さい"
fi

引数を渡して実行

$ bash example.sh 4 8 #(引数0($0);example.sh、引数1($1);4、引数2($2);8に相当)
hello.sh 
1番目の引数が2番目の引数より小さい 

if文の癖

if文の後ろには条件式ではなく、コマンドを書きます。結果として、真or偽で判断するのではなく、終了ステータスが0or0以外かで判断します。

example.sh
#!/bin/bash

if grep -q 'shellscript' /etc/passwd ;then
    echo "shellscript found"
fi

では、a>bなどの条件式を書きたい場合はどうするのか?
その場合はtestコマンドを使います。testコマンドは [ と表記します。

example.sh
# '['はただのカッコではなくコマンドです。最後の引数は']'で終わる決まりがあります。
# 下の例だと、[ コマンドの第一引数は"$1", 第二引数は-gt, 第三引数は"$2",第四引数は ]になります。
# あくまでコマンドと引数という関係なので全てに間にスペースが必要になります。

if [ "$1" -gt "$2" ]
then
    echo "1番目の引数が2番目の引数より大きい"
elif [ "$1" -eq "$2" ]
then
    echo "1番目の引数と2番目の引数は同じです"
else
    echo "1番目の引数が2番目の引数より小さい"
fi

# -gtは、greater thanの略称で、=を含みません。($1>$2と同義。)
# -eqは、イコールのことです。

シェルスクリプトらしい書き方とは