2014-05-19 (Monday)
■[個人メモ][Shell] シェル変数まとめ
シェル変数を展開方法や、位置パラメータ、特殊変数の存在をよく忘れてしまうので、まとめておく。
変数の展開方法と特殊変数は、数が多いので有用そうなものだけまとめる。
ただ、今回まとめた内容は、主にシェルスクリプトで用いることになると思う。
憶えにくい、タイプ数の多い表記が沢山あるので。
動作を確認した環境
- zsh (5.0.5)
- bash(POSIXモード) (4.3.11)
- mksh (49-1)
- dash (0.5.7-4)
概要
- シェル変数の展開
- 位置パラメータ
- 特殊シェル変数
解説
シェル変数の展開
シェル変数の値をセットする際、変数の使用状況・条件に応じて、セットする値や展開したときの表示を、変更することができる。
条件に応じて変数を設定する主な方法は、以下の通り。
- ${variable:=value}
- ${variable:-value}
- ${variable:?message}
- ${variable:+value}
- ${variable#pattern}
- ${variable##pattern}
- ${variable%pattern}
- ${variable%%pattern}
- ${variable/pattern/new}
- ${variable//pattern/new}
1~4の方法は、コロン':'を省略可能である。コロンを入れた場合、変数がこれまで未使用か、ヌルがセットされているときに、コロン以降の処理をおこなう。
コロンを省略した場合、変数がこれまで未使用のときのみ、コロン以降の処理をおこなう。
${variable:=value}
変数variableを展開する際、variableがこれまで未使用である、もしくはヌルである場合、valueを代入してから展開を試みる。
... # 変数VARは一度も使っていない $ echo ${VAR:=hoge} hoge # 変数VARは未使用であるが、値hogeが表示される $ echo $VAR hoge # 変数VARに値hogeが設定されている
${variable:-value}
変数variableを展開する際、variableがこれまで未使用である、もしくはヌルである場合、valueを代入せずに、valueをそのまま返す。
$ echo ${VAR:-hoge} hoge # 表示される内容は = を使った時と同じ $ echo $VAR $ # ただし変数VARには値hogeが代入されていない
${variable:-value}は、値を変数に代入しないので、位置パラメータのように書込み禁止の変数に用いることができる。また、スクリプトのデフォルト値を設定する際にも有用である。
${variable:?message}
変数variableを展開する際、variableがこれまで未使用である、もしくはヌルである場合、messageを表示する。
${variable:?message}は、変数が未使用、もしくはヌルであるかどうかを確認するために使う。
${variable:+value}
変数variableに値が設定されている場合、設定されている値の代わりにvalueを表示する。variableの元の値は変更しない。また、variableが未使用、もしくはヌルである場合は、何もしない。
$ VAR=piyo # 変数VARに値piyoをセット $ echo $VAR piyo $ echo ${VAR:+hoge} hoge # 値piyoの代わりにhogeが表示される $ echo $VAR piyo # しかし元の値は変更されていない
${variable:+value}は、変数の値を変更せずに、展開した時の値を一時的に変えたい場合に使う。
${variable#pattern}
${variable##pattern}
変数variableの値が、patternで指定したグロッビングパターンにマッチする文字列で始まっていれば、マッチする部分を全て削除した値に展開する。variableの元の値は変更しない。
上記2つの違いは、文字列の照合方法。'#'の場合は最短マッチ、'##'の場合は最長マッチで照合をおこなう。
主に、パスの一部を抜出すときに使う。
$ TMPDIR=/home/hoge/tmp $ echo ${TMPDIR##*/} tmp
${variable%pattern}
${variable%%pattern}
変数variableの値が、patternで指定したグロッビングパターンにマッチする文字列で終わっていれば、マッチする部分を全て削除した値に展開する。variableの元の値は変更しない。
上記2つの違いは、文字列の照合方法。'%'の場合は最短マッチ、'%%'の場合は最長マッチで照合をおこなう。
上記の'#'と組合わせれば、ある文字列の中間部分だけを抜出すこともできる。
${variable/pattern/new}
${variable//pattern/new}
変数variableの値のうち、patternにマッチする部分をnewに置換した値に展開する。variableの元の値は変更しない。
上記2つの違いは、文字列の置換方法。'/'の場合は初めにマッチした部分のみを、'//'の場合はマッチすたもの全てを置換する。
簡易sedのように使えるので、様々な場面で役に立つ。
位置パラメータ
位置パラメータを表す変数は、以下の5種類。
- $0
- ${1..9}
- $#
- $*
- $@
- 位置パラメータを使う上での注意点
- 位置パラメータは、$0から$9までの、10個までしか扱えない
- 10個より多くの位置パラメータを使いたい場合は、shiftコマンドを利用して、位置パラメータをずらしていく。
※ 例
$ cat shift_test.sh #!/bin/sh shift # 位置パラメータを左に1つずらす echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 shift 3 # 位置パラメータを左に3つずらす echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $ sh shift_test.sh a b c d e f g h i j k l m n hoge.sh b c d e f g h i j hoge.sh d e f g h i jk l
$0
コマンド自身を表す。
${1..9}
第1, 第2, ..., 第9引数を表す。
$#
位置パラメータの個数を表す。
※ 例
$ cat param_test.sh #!/bin/sh echo $# $ sh param_test.sh hoge piyo hogepiyo 3 $ sh param_test.sh "hoge piyo hogepiyo" 1
$*
$@
引数全体を表す。
$*と$@の大きな違いは、ダブルクォートで囲み、展開した場合の動作にある。
$*は、引数全体をダブルクォートで囲んだ状態にして展開する。$@は、引数1個1個をダブルクォートで囲んだ状態にして展開する。
また、位置パラメータが無い場合、$@はヌル、$*は""に置換される。
特殊変数
主要な特殊変数は、以下の4種類。
- $?
- $$
- $!
- $-
$?
コマンド実行時の終了ステータスを表す。ただし、バックグラウンドで実行させたコマンドに対しては無効。
終了ステータスは、プログラムに依存するが、大抵の場合は、正常終了:真(0)、異常終了:偽(0以外)の値がセットされる。
$$
現在動作しているコマンドのプロセスIDを表す。
プロセスIDは一意であるということを利用して、一時ファイルの命名など、ユニークな番号を付けたい場合に役に立つ。
※ 例
$ touch /tmp/hogehoge.$$
$!
バックグラウンドで実行させたコマンドのプロセスIDを表す。
waitコマンドと組合せて、バックグラウンドジョブが終了するのを待ちたい場合に役に立つ。
※ 例
$ rsync -a hoge piyo & # バックグラウンドでrsyncを実行する ... # rsyncが実行している間に、rsyncに依存しない処理をおこなう。 $ wait $! # rsyncが終了するまで待つ ... # rsyncの実行結果に依存する処理をおこなう
$-
シェル起動時オプション、およびsetコマンドを使って設定したオプションの一覧を表す。
※ 例
$ echo $SHELL /usr/bin/dash $ echo $- smi # オプション:s, m, iがセットされている $ set -o vi # オプション:V(vi-keybind)を追加 Vsmi # オプションにVが追加された
参考書籍
- Bruce Blinn、山下哲典(訳):入門UNIXシェルプログラミング 改訂第2版、pp.40-56、Softbank Creative(2003)
- 広瀬雄二:zshの本、pp.195-201、技術評論社(2009)
雑記
- "=-?+"を使ったシェル変数の設定は、ややこしくて憶えにくい。参考書籍1にも書いてあるけれど、可読性を良くするなら、if文で代用したほうが良いかもしれない。
- 変数の展開には、値の柔軟な変更ができる${variable:#pattern}もある。けれど、zshしか使えない上に、動作を変更できるフラグが非常に多いので、今回は割愛。
- 15 https://www.google.co.jp/
- 8 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCcQFjAA&url=http://d.hatena.ne.jp/gin135/20140502/1399022358&ei=J7N6U_fWHcKpkAWOp4DIBQ&usg=AFQjCNHarWMYouqz3r3Z2Rb5dgQlTY4p7Q&bvm=bv.67229260,d.dGI
- 3 http://d.hatena.ne.jp/
- 3 http://pipes.yahoo.com/pipes/pipe.info?_id=VPw6npu13RGKo15vBRNMsA
- 2 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=0CDcQFjAC&url=http://d.hatena.ne.jp/gin135/20140502/1399022358&ei=jNZ8U9K1B4398QWYsIDYCw&usg=AFQjCNHarWMYouqz3r3Z2Rb5dgQlTY4p7Q&bvm=bv.67229260,d.dGc&cad=rja
- 1 http://search.yahoo.co.jp/search?p=サウンドカード デフォルト 変更&aq=-1&oq=&ei=UTF-8&fr=top_ga1_sa&x=wrt
- 1 http://search.yahoo.co.jp/search?p=デュアルブート+時間ずれる&aq=-1&oq=&ei=UTF-8&fr=top_ga1_sa&x=wrt
- 1 http://websearch.rakuten.co.jp/?tool_id=1&rid=2000&ref=ff&qt=windows7 centos デュアルブート 時間がくるう
- 1 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=3&ved=0CDcQFjAC&url=http://d.hatena.ne.jp/gin135/20140304/1393943319&ei=jRV8U9nSKo7PlAWyqIB4&usg=AFQjCNEH2Ulwew1nZlokxTsKDL_peAMoZA&bvm=bv.67229260,d.dGI
- 1 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CDEQFjAB&url=http://d.hatena.ne.jp/gin135/20140304/1393943319&ei=Qbx5U7_-G8SB8gWasYDAAg&usg=AFQjCNEH2Ulwew1nZlokxTsKDL_peAMoZA&bvm=bv.66917471,d.dGc