シェルスクリプトの基礎
僕の場合、組み込み系の仕事でメインで、主にC言語のみの作業でありますが、作業スタイルを考えるとWindowsマシンからターミナル経由でリモートで作業用のLinuxサーバーへアクセスし、テキストベースで全ての作業しています。
この時勢にGUIはエクセルでデータを編集するときくらいしか使わず、ほとんどテキストベースの端末でいろいろやっております。
そうなると、テキストエディターとちょっとした連続動作などはシェルスクリプトのお世話になることが多いため、スクリプトについて何も知らずとも意外と知らずに使っていておりました。シェルスクリプト。
今日は、そのシェルスクリプトの基礎を勉強用にまとめてみることにしました。
今までの使い方として、ただバカみたいに、Linuxのコマンドをテキストでならべて、連続実行させることが主な使用用途ではありましたが、実際のところ、ただコマンドを上から順に実行していくだけでけでなく、C言語みたいに処理を条件により分岐させたりすることも可能であったりで、ちょっとしたプログラミングぽいことも可能ですよね。
速度の面では、C言語で書かれてコンパイル済みのオブジェクトには叶わないのですが、インタプリターの強みであるコードベースで実行させることになるので、使う環境に影響を受けずに保守メンテも簡単であります。
今までなんでもかんでもC言語に頼るくせからも少しは脱却せねばならないと思っています。
シェルスクリプトとは、
シェルスクリプトとはただのテキストファイルであります。テキストファイルの先頭行に「#!/bin/sh」と書いとけば、Linuxが勝手に先頭の行をみて、そこに書かれたシェルスクリプトを起動させて、テキストの中身の平文をシェルに投げて、シェルがそれを解析してコマンドを代わりに実行してくれることをしてくれるのです。
シェルとは上記に書いてある、「/bin/sh」というコマンド(アプリケーション)であります。
※シェルはBシェル(sh)、Cシェル(csh)、バッシュ(bash)などいろいろありどれを使ってもよさげです。
- #!/bin/sh
- #!/bin/csh
- #!/bin/bash
しかし、テキストファイルだと作成されたファイルに実行権限が付与されないはずなので、作成したテキストファイルをchmodコマンドで実行権限をつける必要があります。
>ls -l
-rw-rw-r-- 1 work work 72 10月 01 18:20 poi.sh
↓>chmod 777 poi.sh
-rwxrwxrwx 1 work work 72 10月 01 18:20 poi.sh
または、
>chmod +x poi.sh
-rwxrwxr-x 1 work work 72 10月 01 18:20 poi.sh
※実行権限は、3bit-3bit-3bitで構成されており、7(2進111)で全ビット有効となります。
※拡張子は「.sh」とつけたりすることが多いですが、実際になくても構いません。
1.C言語のincludeを使いたい場合
シェル記述「#!/bin/sh」しなくてもいいのでテキストだけで設定変数などの定義ファイルを作り、シェルファイル内で、
#!/bin/sh
. ./test.txt
echo $USER # test.txt内に$USER変数が定義済みという前提
と記述するだけ、「.」はbashの場合「source」と書いてもいい、bashのほうがいい気がする。
2.C言語のprintfみたいに数値や文字列を制御したい場合
linuxコマンドでprintfがそのまま使える。たとえば、数値をゼロパディングして文字列を作る場合。
#!/bin/sh
for(( i=0; i<=5; i++ )) {
num=`printf %05d ${i}`echo "file name is text_${num}.txt"
}
※text_00000.txt ~ text_00005.txtと表示される。
3.シェルの実行結果をファイルに残すとき、エラー文言が残らない場合。
標準出力とファイル出力を同時に行いたい場合
$ sh ./test.sh | tee test.log 2>&1
foo
cat: ./sonna_file_naiyo.txt: No such file or directorybar
$ cat test.log
foo
bar
ファイル出力のみを行いたい場合
$ sh ./test.sh > test.log 2>&1
$ cat test.log
foocat: ./sonna_file_naiyo.txt: No such file or directory
bar
4.C言語のように関数を使いたい場合
シェルスクリプト内で以下のように定義が可能である
※functionは省略可能である
# 関数の定義(※定義時は関数名に「( )」を付ける)
function 関数名() {
処理return 値
}
function poi() {
echo $1
return 0
}
定義した関数をコールする場合は以下のように使う
# 関数の呼び出し(※呼び出し時は「( )」は不要)
関数名 引数リスト
poi "test"
関数の戻値は、0~255までの整数値しかできない
func() {
echo "これが戻り値です。"
}rtn=`func`
echo "戻り値=${rtn}"
関数の引数
#!/bin/bash
func() {
echo "\$0=$0"echo "\$#=$#"
echo "\$@=$@"
echo "\$*=$*"
echo "\$1=$1"
echo "\$2=$2"
echo "\$3=$3"
}
func 001 002 003
5.C言語のグローバル変数とローカル変数のような関係の場合
シェルスクリプトでは、関数の外で定義された変数はグローバル変数としてどこの関数からも参照可能です。
関数の中で定義されたローカル変数は、関数の中だけで有効です。
ここまではC言語となんら変わりなのですが、関数の中でグローバル変数と同じ名前のローカル変数が設定可能なのです。
#!/bin/bash
var="global"
LocalVar() {echo "$var" # "global"が出力
# ローカル変数として宣言 (readonly のグローバル変数はローカル変数として再定義できない)
local var="local" # これ以後関数内ではグローバルのvarは参照できない
echo "$var" # "local"が出力
}echo "$var" # "global"が出力