2013/04/25

Shell変数

基礎

シェル変数の特徴的な部分は、定義と参照で表記が変わる点です。
定義の際は、「変数=値」といったスタイルで記載しますが、参照の際は、「${変数}」という形で変数を表記します。
もう一つ定義する際は、「=」と変数、値の間は連続している必要があります。スペースなどを間に入れてしまうとエラーになるので注意が必要です。

位置パラメータ

シェルスクリプトで引数を利用するときに必要な概念です。
スクリプト実行時に渡された引数は、位置パラメータという特殊な変数を通して参照します。
位置パラメータは、ドル記号「$」とそれに続く数字1文字で構成されます。$1 $2 $3 ・・・といったスタイルで、数字の部分が引数の位置を表します。
数字1文字と書きましたが、これでは9個までしか引数を受け取れないということになってしまいます。9個以上の引数を扱いたい場合は、「shift」コマンドを利用します。shiftコマンドを実行すると位置パラメータが参照する引数がずれる、つまり$1が第2引数、$2が第3引数を参照するといった具合です。
例えば、以下の内容でtest.shを作成し、実行してみると動きがわかります。

#!/bin/sh

while [ 0 -le $# ]
do
  echo $1
  shift
done
実行すると10個以上の引数をshiftコマンドを使って参照をずらし$1で順番に参照できているのが分かります。
$ sh test.sh a b c d e f g h i j k l m
a
b
c
d
e
f
g
h
i
j
k
l
なお、「$#」は引数の数が可能される特殊変数の一種です。 では、test.shを以下の通り変更するとどうなるか見てみましょう。
#!/bin/sh

while [ 0 -le $# ]
do
  echo $1
  shift 2
done
実行例は以下の通りです。
$ sh test.sh a b c d e f
a
c
e
上記の実行例を見ると分かると思いますが、参照が2個づつスライドしています。このようにshiftコマンドにスライドさせたい数をしていることで指定した数だけ参照をずらすことが可能です。 もう1とつ忘れていけないのが「$0」は何を参照しているかということです。
#!/bin/sh

echo $0
実行例は以下の通りです。
$ sh test.sh
test.sh

$0は上記の通りスクリプト名を参照しています。

特殊変数

$-(ダラー・ハイフン)

シェル起動時のフラグを保持しています。
シェル起動時のフラグとはシェルオプションと言われるもので、$-は有効になっているシェルオプションを表現するフラグの文字列として表現したものです。
この変数の内容を出力していみると以下のように表示されます。このhimBHという文字列がシェル起動時のフラグです。

 $ echo $-
 himBH

ではシェルオプションにはどういったものがあるか見てみます。シェルオプションの一覧を表示するにはsetコマンドを使います。出力例は以下の通りです。
$ set -o
allexport       off
braceexpand     on
emacs           on
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      on
history         on
igncr           off
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off

各シェルオプションとフラグの関係は下表の通りです。

シェルオプション フラグ 説明
allexport a 変数代入時に自動的にexportを実行する。
braceeexpand B プレース展開を有効にする。
emacs - emacs入力モードを有効にする。
errexit e コマンドが異常終了ステータスで終了するした場合にシェルを終了する。
errtrace E
functrace T
hashall h コマンドの位置を記憶し、検索時間を短縮する。
histexpand H !(exclamation point:エクスクラメーション・ポイント)によるヒストリの置換を有効にする。
igncr -
ignoreeof -
interactive-comments -
keyword k ?
monitor m ジョブコントロールを有効にする。
noclobber C すでに存在するファイルへのリダイレクトを禁止する。
noexec n
noglob f ワイルドカード(*、?)の展開を禁止する。
nolog -
notify b バックグラウンドジョブが終了した際の通知を有効にする。
nounset u 未設定パラメータへの参照をエラーにする。
onecmd t ?
physical P cd/cwdで-Pオプション(シンボリックによるパスではなく実際のパスを表示)を常に有効にする。
pipefail -
posix -
plivileged p 特権モードを有効にする。
verbose v コマンド入力時にエコー表示する。
vi - vi入力モードを有効にする。
xtrace x コマンド実行時に、展開後のコマンド行表示を有効にする。
対話モードの場合はiフラグが立ちます。以下のように対話モードであるか検出する例を見かけたりします。
[[ "$-" != *i* ]] && return

ブレース展開

{}(ブレース)で囲まれた短縮表現を展開することです。
呼んでもサッパリ分からないと思いますので、とりあえず以下の例を見てください。

 $ echo {a..z}
 a b c d e f g h i j k l m n o p q r s t u v w x y z
{}(ブレース)で囲まれた短縮表現の「a..z」が展開されて出力されているのが分かると思います。
また、固定の文字列と組み合わせてこんな使い方もできます。
 $ for v in test_{01..09}.log; do
 > echo ${v};
 > done
 test_01.log
 test_02.log
 test_03.log
 test_04.log
 test_05.log
 test_06.log
 test_07.log
 test_08.log
 test_09.log
可変部分を短縮表記でなくても動作します。
 $ for v in test_{a,b,c}.log; do
 > echo $v
 > done
 test_a.log
 test_b.log
 test_c.log
空文字的なものも含めることができます。
 $ for v in test{,.log}; do
 > echo ${v}
 > done
test
test.log
*(アスタリスク)も利用できます。アスタリスクは該当するファイル名に展開されるようです。
 $ echo {.vimrc,.*}
 .vimrc . .. .bash_history .bash_profile .bashrc .gem .gitconfig .inputrc .profile .screenrc .ssh .vim .viminfo .vimrc

0 件のコメント:

コメントを投稿