最終更新:2017-02-17 (金) 16:38:09 (2787d)
シェルスクリプト
Top / シェルスクリプト
http://www.linux.or.jp/JM/html/GNU_bash/man1/bash.1.html
基本
先頭に
#!/bin/sh
と書く
予約語
! case do done elif else esac fi for function if in select then until while { } time [[ ]]
コメント
#ほげほげ
シェルスクリプト/変数
シェル変数
- 変数に値を代入するには「変数名=値」とします。「=」の前後にはスペースやタブを入れることはできません。
- 変数を参照する場合は、変数名の前に「$」を付けます。
var="ほげほげ" echo $var
- 変数参照時に変数が誤解釈されそうな場合には「""」または「{ }」で変数名を囲む。
var2=${var1}0
変数の展開など
- 引用符
記号 意味 '...' 内部の文字列をそのままの文字列として返す. "..." 内部に含まれる変数等 $,`...`,\ を解釈した結果の文字列を返す `...` 内部にあるコマンド(群)を実行し, その標準出力を文字列として返す.
引数
- 受け取った引数は、$1から$9という変数に格納される
echo $1
特殊な変数
- 特殊変数一覧 (シェルスクリプト/変数)
変数 意味 $$ シェル自身のPID(プロセスID) $!? シェルが最後に実行したバックグラウンドプロセスのPID $? 最後に実行したコマンドの終了コード(戻り値) $-? setコマンドを使って設定したフラグの一覧 $* 全引数リスト。"$*"のように「"」で囲んだ場合、"$1 $2 … $n" と全引数を一つにくっついた形で展開される。 $@ 全引数リスト。"$@"のように「"」で囲んだ場合、"$1" "$2" … "$n" とそれぞれの引数を個別にダブルクォートで囲んで展開される。 $♯ シェルに与えられた引数の個数 $0 シェル自身のファイル名 $1~$n シェルに与えられた引数の値。$1は第1引数、$2は第2引数…となる。
未設定変数など
- 空かどうか
書式 変数が空でないとき 変数が空のとき ${変数 :-word } 変数 の値が使われる word の値が使われる ${変数 :=word } 変数 の値が使われる word の値が変数に代入されて使われる ${変数 :?word } 変数 の値が使われる word がエラーメッセージとして使われ、スクリプトが終了する ${変数 :+word } word が変数 に代入される 何もしない
- 定義済みかどうか
書式 変数が定義されているとき 変数が定義されていないとき ${変数 -word } 変数 の値が使われる word の値が使われる ${変数 =word } 変数 の値が使われる word の値が変数に代入されて使われる ${変数 ?word } 変数 の値が使われる word がエラーメッセージとして使われ、スクリプトが終了する ${変数 +word } word が変数 に代入される 何もしない
文字列演算子
- オフセットとか
使い方 意味 目的 例 ${varname:offset} ${varname:offset:length} サブ文字列を展開する. offsetの位置からlength文字 の長さのサブ文字列を$varnameの値から取り出す. 文字の位置は0からカウントする. lengthが省略された場合, offsetの位置から $varnameの終りまでのサブ文字列が返される. offsetが0より小さかった場合, 開始位置は $varnameのおわりからカウントされる. varnameが@の場合, lengthはoffsetを先頭とする 位置パラメータの番号になる. 文字の一部を返す(サブ文字列またはスライスという). countがfrogfootmanと設定されている場合, ${count:4}はfootmanを返し, ${count:4:4}はfootを返す. ${#varname} $varnameの文字数(全角文字も1文字)になる ${varname#接頭辞} $varnameから一致する最小部分の接頭辞を削除したもの ${varname##接頭辞} $varnameから一致する最大部分の接頭辞を削除したもの ${varname%接尾辞} $varnameから一致する最小部分の接尾辞を削除したもの ${varname%%接尾辞} $varnameから一致する最大部分の接尾辞を削除したもの
配列
- 配列を扱うことも出来る
NAME[0]=value NAME=(value1 value2 …)
指定方法 説明 ${NAME[n]} 指定された要素の内容。 ${NAME} ${NAME[0]}と同じ。 ${NAME[*]} 配列内の全要素。 ${NAME[@]} ${#NAME[n]} 指定された要素の文字数。 ${#NAME} ${#NAME[0]}と同じ。 ${#NAME[*]} 配列の要素数。 ${#NAME[@]}
ワイルドカード
- * , ? , [ , ] の各特殊文字はワイルドカードと呼ばれ,任意のコマンド中でファイル名を指定するときに利用できる
- シェルはそのパターンにマッチしたファイル名を探して、 自動的に完全なファイル名に直してコマンドを実行してくれる
ワイルドカード 意味 * 任意(0文字以上)の文字列 ? 任意の1文字 [ ] 中に指定されたうちの一文字 [! ] の中に指定された文字以外の一文字 {文字列1,文字列2,...} 文字列1あるいは文字列2あるいは...というように可能性の ある文字列をいくつか列挙する
- *はカレントディレクトリの全ファイルに置き換わる
コマンドシーケンス
コマンドの慣用句 説明 command & command をサブシェル中でバックグラウンド実行 command1 | command2 command1 の標準出力を command2 の標準入力に パイプ (同時並行で実行) command1 2>&1 | command2 command1 の標準出力と標準エラー出力を command2 の標準入力にパイプ (同時進行で実行) command1 ; command2 command1 を実行し、後に続いて command2 を実行 command1 && command2 command1 を実行; もし成功したら、 後に続いて command2 を実行 (command1 と command2 の両方が成功したら、正常終了を返す) command1 || command2 command1 を実行; もし成功しなかったら、後に続いて command2 を実行 (command1 か command2 のどちらかが成功したら、正常終了を返す) command > foo command の標準出力を foo ファイルにリダイレクト (上書き) command 2> foo command の標準エラー出力を foo ファイルにリダイレクト (上書き) command >> foo command の標準出力を foo ファイルにリダイレクト (追記) command 2>> foo command の標準エラー出力を foo ファイルにリダイレクト (追記) command > foo 2>&1 command の標準出力と標準エラー出力を foo ファイルにリダイレクト command < foo command の標準入力を foo ファイルからリダイレクト command << delimiter command の標準入力を "delimiter" に出会うまでのこれに続く行からリダイレクト (ヒアドキュメント?) command <<- delimiter command の標準入力を "delimiter" に出会うまでのこれに続く行からリダイレクト (ヒアドキュメント?、行頭のタブ文字は入力から削除)
演算
- exprコマンドを使う
#!/bin/sh A=1 B=2 C=`expr ${A} + ${B}` echo ${C} #3と表示
#!/bin/sh A=1 B=2 C=`expr ${A}+${B}` #スペースで区切らないと echo ${C} #1+2と表示される
- exprの演算子
演算子 意味 a + b aとbの和 a - b aとbの差 a \* b aとbの積 a / b aとbの商 a % b aとbの剰余
- 乗算の演算子は「*」ですが、UNIXでは「*」はワイルドカードという特別な意味がありますので、エスケープ文字「\」を使用して「\*」と書く
- 演算子の前後のスペースは省略できない
論理結合
- if文やwhile文で、複数の条件を結合(AND,OR)して評価したい場合は、以下のように記述します。
論理結合演算子 意味 ! 条件 条件が偽であれば真 条件1 -a 条件2 条件1が真、かつ、条件2が真であれば真 条件1 -o 条件2 条件1が真、または、条件2が真であれば真
制御構文
if文
- 例
if 条件1 then 処理1 elif 条件2 then 処理2 else 処理3 fi
if [ $hoge = $fuga ]; then echo "文字列は同じです" else echo "文字列は違います" fi
if cat $file >/dev/null; then echo here; else echo absent; fi
if cat $file >/dev/null then echo here else echo absent fi
[ ]構文
- 内部組み込みコマンド(同内容の外部コマンドも /usr/bin/test? にある)「test」の判定と同じ
#!/bin/sh #ファイルが存在すれば削除 TEST_FILE=/home/hoge/test.txt if [ -e ${TEST_FILE} ] then rm ${TEST_FILE} echo "removed "${TEST_FILE} else echo ${TEST_FILE}" is not existed." fi
- 数値比較
表現 真($? == 0)を返す場合 num1 -eq num2 num1 = num2 num1 -ne num2 num1 != num2 num1 -gt num2 num1 > num2 num1 -ge num2 num1 >= num2 num1 -lt num2 num1 < num2 num1 -le num2 num1 <= num2
- 文字列比較
表現 真($? == 0)を返す場合 str1 = str2 文字列の一致 str1 != str2 文字列の不一致 -n str 文字列が空ではない -z str 文字列が空である str1 -gt str2 数値表現として、str1 > str2 str1 -ge str2 数値表現として、str1 >= str2 str1 -lt str2 数値表現として、str1 < str2 str1 -le str2 数値表現として、str1 <= str2 ! 結果の真偽を逆転する
- ファイルに対する処理
表現 真($? == 0)を返す場合 -d file ファイル名がディレクトリである -e file ファイル名が存在する -f file ファイル名が通常ファイルである -r file ファイル名がパーミッションの上で読むことができる -s file ファイル名が存在し、かつ空ではない -w file ファイル名がパーミッションの上で書き込むことができる -x file ファイル名がパーミッションの上で実行可能である -O file そのファイルの所有者である -G file そのファイルの所有者と同じグループに属する file1 -nt file2 更新時間を比較し、file1 の方が新しい file1 -ot file2 更新時間を比較し、file1 の方が古い
for文
- 基本
for 変数 in 値リスト do 処理 done
- 例
for i in 1 2 3 4 5 do echo $i done
- 基本2
for (( 初期化 ; 継続条件 ; 再初期化 )) do 変数を使用する処理 done
- コマンドの実行結果を値リストに指定する
for var in `コマンド` do 処理 done
- 例
#for var in `ls -1`と同じ処理? # in に続くリストがワイルドカード展開されて、カレントディレクトリのすべてのファイルになる for file in * do if [ -d $file ]; then ls -d $file; fi done
#!bin/sh for srcname in `find /home/hoge/programming/c | egrep '.+\.c$'`;do case `basename $srcname` in a.c | b.c | c.c) ;; # exclude *) # C言語のソースファイルに何かする esac done
- 例
case文
- 例
case 変数 in パターン1) 処理;; パターン2) 処理;; パターン3 | パターン4) 処理;; *) 処理;; esac
- ;;は「case文を抜ける」という意味
- *)は「いずれのパターンにもあてはまらない場合」という意味で、省略可能
- パターンを「 | 」で区切って論理和(or)をとることも可能
- パターンには正規表現が使える
case "$var" in a* ) echo "aで始まる文字列" ;; ?b* ) echo "2文字目がbの文字列" ;; [A-Z]* ) echo "大文字で始まる文字列" ;; [!xX]* ) echo "先頭がxではない文字列" ;; * ) echo "上記のいずれでもない文字列" ;; esac
while文
until文
select文
- メニューを表示してユーザに選択を促す(プロンプトが表示される)ようなスクリプトの記述ができる
select 変数 in リスト do 内容 done
select 変数 in リスト; do 内容 done
テキスト処理
制御構文whileやforを避ける方法
関連
参考
- http://www.k4.dion.ne.jp/~mms/unix/shellscript/index.html
- http://www.ep.sci.hokudai.ac.jp/~inex/y2002/1101/1101_script.html
- http://www.geocities.jp/geo_sunisland/tips.html
- http://www.nurs.or.jp/~sug/soft/super/bash.htm
- http://chaichan.web.infoseek.co.jp/src/BSH.htm
- http://www.ibm.com/developerworks/jp/linux/library/l-bash.html
- http://www.ne.jp/asahi/hishidama/home/tech/unix/sh.html