Edited at

シェルスクリプトのTips

More than 3 years have passed since last update.

シェルスクリプトを勉強していて少しややこしいところがあったので、まとめてみました。


メタキャラクタについて

「"・・・"」で括った文字列の中で「”」や「$」などの特殊記号を使いたい場合はメタキャラクタを使います。


シェルスクリプト中に文字列を書く場合

①”・・・”

②'・・・'

③括らずに書く

の3種類がある。

①の場合、括られた全体がひとつの文字列として扱われます。括られた文字列の中では変数の展開・コマンド置換・メタキャラクタなどの各種展開が可能!

文字列中に「"」や「$」を含めたいときは「\"」「\$」のようにする。

②の場合、①と同じように括られた全体がひとつの文字列として扱われます。

但し、変数の展開等が行われません。

③の場合、変数の展開などが行われます。ただし空白などで単語を区切ると単語ごとに扱われます。


変数の値を書き換えられないようにする

readonlyコマンドを使う。


$*と$@の違い

\$*と\$@はどちらも引数全体を表しますが

例えば引数が「a b c」の場合、

\$*は引数全体をひとつの文字列をして扱うので「a b c」となります。

$@はひとつひとつの引数を括って並べたものになるので「"a" "b" "c"」となります。


特殊記号$について

\$1~\$9は引数を表す。

\$?は最後のコマンドの終了コードを表す。

\$0はシェルスクリプト自身のファイル名を表す。

\$#は引数の個数を表す。


「--」について

様々なシェルスクリプトを見ると、

set -- $i

のように「--」というのを見ることがある。

なぜ「--」が必要かと言うと、

\$iが「-x 」という文字列で開始された場合にオプション変更だと解釈されてしまいます。これを防ぐために、「--」を入れて「これ以降はオプション設定ではない」と明示します。


配列変数を参照する場合、「{」「}」を使う

sample[0]="zero"

sample[1]="one"
sample[2]="two"

for i in 0 1 2;do
echo "sample[$i]=${sample[$i]}"
done


配列の区切り文字としてシェル変数IFSが使われる

sample[0]="hello"

sample[1]="world"
sample[2]="Hi!!"

IFS=":"

echo "${sample[*]}"

結果

hello:world:Hi!!


改行で表示することも出来る

sample3[0]="hello"

sample3[1]="world"
sample3[2]="Hi!!"

#改行
IFS=$'\n'

echo "${sample3[*]}"

結果

hello

world
Hi!!


標準エラー出力にメッセージを出力する

メッセージを標準出力ではなく、標準エラー出力したい場合には、リダイレクトして「>&2」とする。

エラーメッセージを標準出力に書き込むように設定するとメッセージが混じって不便なので、なるべく分けるようにしたほうが良いと思います。