はじめに

#!/bin/bash

shebang には bash を明記する。 /bin/sh は Bourne Shell への simlink になっていて、bash じゃないこともあるので。

変数とか

hoge='hello,world shell'
echo $hoge         # hello,world shell
echo ${hoge}script # hello,world shellscript

declare -ri v=42 # 整数型(i)のread-only(r)変数

# 配列
declare -a arr=(alice bob charlie [4]=eve)
echo ${arr[0]} #=> alice
echo ${arr[3]} #=> 空文字列
echo ${arr[4]} #=> eve
echo ${!arr[@]} # 0 1 2 4 # 値の存在するインデックス
arr[3]=dave # 値をセット
echo ${#arr[@]} #=> 5 # 要素の数
echo ${arr[@]} #=> alice bob charlie dave eve #

declare -a arr2=(zero "${arr[@]}" frank) 
# 配列のコピー&要素の追加。
# [@]は "$arr[0]" "$arr[1]" ... として展開される。
echo ${arr2[@]} #=> zero alice bob charlie dave eve frank

arr+=(frank george) # 末尾ならこういう追加もできる
echo ${arr[@]} #=> alice bob charlie dave eve frank george

# 連想配列
declare -A map=([a]=alice [b]=bob [c]=charlie)
echo ${map[b]} #=> bob
map[e]=eve
unset map[b] # 値の削除
echo ${#map[@]} #=> 3 # 要素の数
echo ${map[@]} #=> eve charlie alice # 値一覧
echo ${!map[@]} #=> e a c # キー一覧

環境変数

シェルからコマンド実行すると別のプロセスとして実行されるが、この別プロセスへ引き継がれる変数を環境変数という。

TARGET=/home/tac        # これはただたの変数で、子プロセスには引き継がれない
export TARGET=/home/tac # exportすると環境変数になる
TARGET=/home/tac ls     # この子プロセス実行時だけ引き渡すこともできる

# 事前定義済み環境変数の場合はあらためてexportする必要はない
LANG=ja_JP.UTF-8

特殊なシェル変数

位置パラメータ

#!/bin/bash

# ./tmp.sh aaa bbb ccc

echo $0    # ./tmp.sh # 実行したスクリプトへのパス
echo $1    # aaa # 第1引数
echo $3    # ccc # 第3引数
echo $38   # ccc8 # $9以上は中括弧で囲って参照する必要がある
echo ${38} #  # 与えられてない引数は空文字列扱い
echo $@    # aaa bbb ccc # 引数を展開
echo $*    # aaa bbb ccc # 引数を展開。あんまり使わない
echo "$@"  # aaa bbb ccc # "$1" "$2" "$3" それぞれ別の文字列として展開。ループとかできる
echo "$*"  # aaa bbb ccc # "$1 $2 $3"  スペース区切りの1つの文字列として扱われる。あんまり使わない

echo $# # 3 個数
echo $? # 0 直前に実行したコマンドの終了ステータス。0なら成功、それ以外なら失敗になっていることが多い
echo $$ # 6467 # 現在のPID
echo $! # 6464 最後に実行したバックグラウンドプロセスのPID。なければ空文字列。
        # バックグラウンド実行して監視したり、あとから殺すために変数に入れておいたりする。