Bashシェルスクリプト
2019/03/23
Index
シェルスクリプトの役割 : [To Index]
  • コンピュータを使用するとき我々は何らかのシェル(Shell)を経由して目的の操作を行っています。

  • 例えばファイルリストの取得は
    $ ls
    Desktop Documents Downloads Music Pictures Public Templates Tmp Videos
    のように ls コマンドを使います。このコマンドを入力するインターフェースが既にシェル(*1)です。

  • もう少しシェル上で多くの操作をしてみましょう。例えば
    • 音楽データディレクトリから Coldplay のflacデータを探す (findを使用)
    • 探したflacデータを tar ファイルにまとめる (tarを使用)
    • 各flacデータのサイズを表示する (wc -cを使用)
    といった操作は下記のように行うことができます。
    $ find /home/share/music -name "*.flac" | grep "/Coldplay/" > music.list
    $ tar cvf Coldplay.tar -T music.list
    $ sed 's/^/wc -c "/' music.list | sed 's/$/"/' > music_wc_byte.scr
    $ source music_wc_byte.scr

  • こういった操作をする機会が多いのであれば、シェル上で入力するコマンド群を予めファイルに書いておき、そのファイルを実行すれば楽だと考えるのが自然でしょう。それがシェルスクリプトです。

  • なので、もっとも単純なシェルスクリプトは、上記のコマンド群を単にファイルへ書き出したものになります。
    find /home/share/music -name "*.flac" | grep "/Coldplay/" > music.list
    tar cvf Coldplay.tar -T music.list
    sed 's/^/wc -c "/' music.list | sed 's/$/"/' > music_wc_byte.scr
    source music_wc_byte.scr

  • 例えば music_tar_byte.scr というファイルに上記コマンドを記述したのであれば
    $ source music_tar_byte.scr
    または
    $ chmod +x music_tar_byte.scr # 実行権付与
    $ ./music_tar_byte.scr
    といった操作(オペレーション)で、シェルスクリプトを実行することができます。

シェルスクリプトを何に使うか : [To Index]
  • 先程書いたように、シェルスクリプトは、シェル上の操作を予めファイル化したものです。

  • そしてシェルとは、ファイル操作やプログラム実行管理などをOSに命令するインターフェースです。

  • つまりOSに実行させる以上の内容をシェルスクリプトにさせることは避け、そういった操作は各コマンドやプログラムに任せるべきです。

  • 例えば、大抵のシェルスクリプトでは実数計算(*2)ができません。ですがOS操作が主目的のシェルスクリプトで何故実数計算が必要なのでしょうか? それが必要になったとき、そもそもOS操作の一部として行うべきか再検討した方が良いでしょう。

何故Bashシェルなのか : [To Index]
  • 本レポートのタイトルは「Bashシェルスクリプト」ですが、文字通り説明対象のシェルは Bash です。

  • Linuxのシェルには複数の種類があります。sh, csh, ksh, tcsh ... これらのシェルの一つが Bash です。

  • 数あるシェルの中で Bash を選んでいる理由は3点あります。1点目は Bash が事実上 Linux Distributoin の標準シェルになっているからです。

  • 2点目は、csh系に比べて関数を使えるなどスクリプトの記述自由度が高いことです。

  • 昔話になりますが、私のようなおじさんエンジニアは、Linux初期の頃からUnixを触っているため、Bashが存在する前のSunOS/SolarisやFreeBSDも使っていました。その際、Bashの前身.. sh ですが、これはコマンド編集機能が貧弱だったため、インターフェースとしては csh を選んでいました。その勢いでスクリプトも csh が多かったのです。しかしUnixと言えばLinuxといってもほぼ問題ない現状で、csh を使うメリットはありません。コマンドインタフェースもスクリプトも Bash にすれば良いのです。

  • そして3点目ですが、Bash が Windows上で使える/サポートされるようになったからです。

  • 2018/05より Windows Subsystem for Linux が正式サポート(*3)になりました。MS-DOSの頃から存在したコマンドインターフェースは収束してWindows Power Shellへ移行する流れだったものの、大きく変わった文法が通常ユーザから見てとっつきにくく悩んでいました。そこへ渡りに船で Windows Subsystem for Linux が出てきたわけです。

  • これらの理由から、マルチな環境でスクリプトを使用できるシェルとして Bash を選びました。

シバン(shebang) : [To Index]
  • デフォルトのシェルはbashであることがほとんどですが、デフォルトシェルが異なる環境でスクリプト実行するとエラーになってしまいます。

  • そのため、シェルスクリプトでは、スクリプト内で対象となるシェルを明示します。書き方は下記のように、スクリプトの1行目で、#!の後にシェルを指定します。これはbash以外でも同じです(例:#!/usr/bin/perl 等)。
    #!/bin/bash
    ...
    スクリプトの記述
    ...

  • この1行目に書かれる #!
     shell bang 又は sharp bang ... 略して shebang(シバン 又は シェバング)
    となったようです。

シェル変数 : [To Index]
  • シェルスクリプト内で変数を使用できます。下記のように、変数名に"スペース無しで'='と'値'を結びつけて"ください。
  • 変数の値の参照(値の取り出し、デリファレンス)は"変数名に$を付けます"。
  • #!/bin/bash

    loHoge="Hello bash world!!" # loHogeがシェル変数

    echo $loHoge # loHogeの中身は$を付けて参照する

    $ ./test.scr
    Hello bash world!!

  • 間違えて「loHoge = "Hello bash world!!"」のようにスペースを入れると、下記のようにエラーとなります。
    $ ./test.scr
    ./test.scr: 行 3: loHoge: コマンドが見つかりません

  • 変数同士の代入は、参照側で$を付けます。(つまり値渡しです)
    #!/bin/bash

    loHoge0="Hello!!"
    loHoge1=$loHoge0 # 値を代入する
    loHoge0="Bye!!" # 後から書き換える(loHoge1には反映されない)

    echo $loHoge1

    $ ./test.scr
    Hello!!

  • 文字列内で、$で値を参照する(デリファレンス)する変数名を明示化する場合"{}で変数名を囲みます"。
    #!/bin/bash
    
    loHoge0="Hello!!"
    loHoge1=$loHoge0
    loHoge0="Bye!!"
    
    echo "$loHoge1_$loHoge0"     # $loHoge1は変数名の境界が曖昧なので解釈されない
    echo "${loHoge1}_${loHoge0}" # {}で囲めば両方解釈される
    
    $ ./test.scr Bye!! Hello!!_Bye!!

以降追加予定 : [To Index]
  • 変数の説明が続きます。
Notes
  • 最近のUNIXディストリビューションでは多くの場合デフォルトシェルが Bash です。
  • どうしても必要なときは bc コマンドに計算させたりします。
  • Windows 7では、MSYS2 を使えば良いかと思います。
Copyright(C) 2018 Altmo
本HPについて