ShellScriptのまとめ
概要
ShellScriptについて簡単にまとめます。
私はzsh使いですが、この記事ではshを中心に書いています。
Shellの種類と特徴
Shell名 特徴 sh 最初のシェル(Bourneシェル) csh C言語の文法に似たスクリプト用いることができる bash Bourneシェルを拡張したもの(Bourne Again Shell) tcsh cshを拡張したもの ksh 商用UNIX(SystemV)の標準シェル zsh 最強のシェル(bashやtcshの機能を併せ持つ)
基本コマンド
コマンド 説明 Ctrl+H カーソルの左の文字を一文字削除(BSキー) Ctrl+B カーソルを左に移動 Ctrl+F カーソルを右に移動 Ctrl+D カーソル上の文字を一文字削除(Dellキー) Ctrl+K カーソルから右側の文字をすべて削除 Ctrl+S 画面への出力を一時停止 Ctrl+Q 画面への出力を再開 Ctrl+L 画面をクリアー Ctrl+A 行の先頭にカーソルを移動 Ctrl+E 行の最後にカーソルを移動 Ctrl+C プログラムの処理を中止 Ctrl+Z プログラムの処理を一時停止 Ctrl+P 履歴をひとつ前に遡る Ctrl+N 履歴を逆順の遡る !! 直前の実行したコマンドを実行 !-n n回前に実行したコマンドを実行 !n history番号のn番号を実行 !<文字列> 文字列から始まるコマンドの最新のものを実行 !?<文字列>? 文字列を含むコマンドの最新のものを実行 history historyの一覧を表示
文字列比較演算子
演算子 説明 = 両辺の文字列が一致したとき真 != 両辺の文字列が一致しないとき真 -n 変数 変数の長さが0でないときに真 -z 変数 変数の長さが0でであるとき真 ! 変数 変数の長さが0でであるとき真
ファイル属性演算子
※fileという記述のところにファイルパスを指定
演算子 説明 -d file fileが存在してディレクトリのとき真 -e file fileが存在するとき真 -r file fileが読み取り可能なとき真 -w file fileが書き込み可能なとき真 -x file fileが実行可能なとき真 -f file fileが存在し普通のファイルのとき真 -L file fileがシンボリックリンクのとき真 -s file fileサイズが0より大きいとき真 file -nt file2 fileがfile2より新しければ真 file -ot file2 fileがfile2より古ければ真
特殊変数
変数名 説明 $? 最後に実行したコマンドのexit値 0:成功時 1:失敗時 $$ シェル自身のプロセスID $! シェルが最後に起動したバックグラウンドプロセスのプロセスID $- シェルの起動時のフラグ、setコマンドを使って設定したフラグの一覧 $n スクリプトに渡された n番目の引数 (9個まで引数を取れる。$0はスクリプトの名前、 $1は第1引数、...、$9は第9引数) $# シェルに対する引数の個数(引数がない場合は0) $* 全引数リスト。ダブルクォートで囲んだ場合、"$1 $2 ... $n" と全引数を一つにくっつけた物に展開される。 $@ 全引数リスト。ダブルクォートで囲んだ場合、"$1" "$2" ... "$n" とそれぞれの引数を個別にダブルクォートで囲んで展開する。
1行目のおまじない
#!はシバンといいます。以下のプログラムはこれを使うよという意味です。
http://ja.wikipedia.org/wiki/シバン_(Unix)
#!/bin/sh -x といった-xと指定する事でデバックモードで実行できるようです。
変数の使い方
スペースを入れると文法エラーになる。
#!/bin/sh a = "JavaScript" #文法エラー echo $aシングルクォートとダブルクォートの違い
- ダブルクォーテーションはその中にある変数は展開される。
- シングルクォーテーションは文字列定数として扱われる。
※phpなども同様。
#/bin/sh echo '$100' echo "$100"ブレース展開
- 文字列をカンマ区切りで{}でくくるとそれぞれを展開してくれる。
- 例はfor文の項目で利用するファイル配布処理。
#!/bin/sh list=( local{01,02,03}.devs ) for i in ${list[@]} do scp .ssh $i done
配列
定義
#!/bin/sh list=( 1 2 3 ) #以下は上と同義 list[0]=1 list[1]=2 list[3]=3 #参照 echo ${list[0]} echo ${list[1]} echo ${list[2]}for文と利用
- 後で項目を挙げるfor文と配列の組み合わせ
- ${list[@]}は配列の全要素。
- ${#list[@]}となると配列の大きさになる。
#/bin/sh list=(1 2 3) total=0 for a in ${list[@]} do total=`expr $total + $a` done echo $total最後に要素を追加
#/bin/sh list=(1 2 3) list=(${list[@]} 10) echo ${list[@]}2つ以上の配列のマージ
#/bin/sh list=(1 2 3) list2=(4 5 6) list=(${list[@]} ${list2[@]}) echo "${list[@]}"
文字列
例.二つ以上の文字列を連結させる
#!/bin/sh str="Java" str2="Script" dstr=$str$str2 echo $dstr例.特定文字列の長さを取得
#!/bin/sh str="JavaScript" len=${#str} echo $len例.正規表現のマッチ
#!/bin/sh a="JavaScript" if [ `expr $a : "Java"` ] then echo "match" else echo "no match" fi
if文
例.文字列の空判定
- ifと[]の間には半角スペースが必要。
- ifとelifの後には必ずthenを記述する。
- ifの終了となるfiを記述する。
- 慣習的に空文字判定は"x$a" = "x"のように記述する。
#!/bin/sh a="test" if [ "x$a" = "x" ] then echo "Empty" elif [ $a = "test" ] then echo "Match" else echo "Not Match" fi
for文
例.ファイルを配布
- 連続する数を生成する。
- 規則正しいサーバ名に対してファイルを配布する。
- echoで表示し |sh で実行する。
#!/bin/sh for n in {1..10} do echo scp .ssh local$n: | sh done
while文
例.ファイルを配布
- for分の例をwhile文で書いてみる。
- 数値演算子の-leを使う。
#!/bin/sh a=0 while [ $a -le 10 ] do echo scp .ssh local$a.devs: a=`expr $a + 1` done
until文
例.ファイルを配布
- for文の例をuntilを使って書く。
#!/bin/sh a=0 until [ $a == 11 ] do echo scp .ssh local$a.dev a=`expr $a + 1` done
case文
例.引数の値から呼び出すコマンドを変える。
- case文を利用。
- コマンドライン引数を取得
#!/bin/sh case $1 in *.txt) vi $1 ;; *.jpg|*.jpeg) gimp $1 ;; *.mp3) xmms $1 ;; *) echo "I don't know this file." ;; esac例.引数に指定されたファイルの文法チェック
#!/bin/sh case $1 in *.php) php -l $1 ;; *.pl|*.cgi) perl -c $1 ;; *.sh) sh -n $1 ;; *) echo "I don't know this file." ;; esac
関数を使う
例.引数の合計値を出す
- コマンドライン引数を取得する$*を利用する。
- shiftコマンドを利用して$1の変数が次の引数を参照できるようにする。
#!/bin/sh sum() { total=0 while [ $# -ne 0 ] do total=`expr $total + $1` shift done echo $total return 0 } sum $*
応用
例.はてぶの新着エントリーに掲載されているかどうかを確認
#!/bin/sh a=0 acount="yutakikuchi" baseuri="http://b.hatena.ne.jp/entrylist/it?" #loop while [ $a -le 3000 ] do result=`curl $baseuri'sort=eid&of='$a` echo $result | grep -i $acount if [ $? = 0 ] then echo $a" hold=0" >> result.txt fi result=`curl $baseuri'sort=hot&threshold=3&of='$a` echo $result | grep -i $acount if [ $? = 0 ] then echo $a" hold=3" >> result.txt fi result=`curl $baseuri'sort=hot&threshold=5&of='$a` echo $result | grep -i $acount if [ $? = 0 ] then echo $a" hold=5" >> result.txt fi a=`expr $a + 20` done