変数のスコープ
#/bin/sh
#
# コマンドを発行し、とある文字列を検索する
#
do_cmd_grep () {
local CMD=$1 # 関数内ローカル変数として定義
local STR=$2
echo "#DBG#" ${CMD}
echo "#DBG#" ${STR}
# localを付けないと、同一シェル内でグロール
ret_cmd_grep=`${CMD} | grep ${STR} | wc -l`
}
do_cmd_grep "netstat -nr" "^0.0.0.0"
echo ${ret_cmd_grep}
echo "cmd is " $CMD
シェル変数の展開
name=/var/log/boot.log
ーーーーー> boot.log ${name##*/} basename
<ーーーー /var/log ${name%/*} dirname
<ー /var/log/boot ${name%.*} 拡張子なし
ーーーーーーーー> log ${name##*.} 拡張子
# 拡張子変更 /var/log/boot.txt
${name%.log}.txt
1.部分文字列(ゼロオリジン)
${var:n:n} ※ ${var:offset:length}
${var:n}
ここでのn:nはoffset:lengthとなり、変数varのn番目からn個の文学が展開される。
lengthが省略された場合、(offset)番目から最後までが展開される。
2.先頭からマッチした部分を削除する。
${var#pattern}
${var##pattern}
varの値の先頭からpatternにマッチする部分が削除された状態で展開される。
#一つの場合は最短一致、##二つは最長一致となる。patternにはパス名の展開と同じ規則
が適用される。
3.後ろからマッチした部分までを削除 → 拡張子の変更
${var%pattern}
${var%%pattern}
#と逆でvarの値の後ろからpatternにマッチする部分が削除された状態で展開される。
%の場合は最短一致、%%は最長一致となる。patternにはパス名の展開と同じ規則が適用される。
OTF=${INF%m4a}mp3
OTF=`echo $INF | sed s/mkv$/mp4/`
4.置換
${var/pattern/str} 最初だけ置換
${var//pattern/str} 全部置換
${var/pattern} パターンを削除
${var//pattern} パターンを削除
varの値のうちpatternにマッチする部分がstrに置換された状態で展開される。
/の場合は最初にマッチした部分のみが、//の場合はマッチする部分すべてが置き換えられる。
初期値
hoge | :+ | + | :ー | ー | |
---|---|---|---|---|---|
定義済& notNULL | hoge="Hello" | 変更 | 変更 | そのまま | そのまま |
定義済& Null | hoge="" | Null | 変更 | 変更 | そのまま |
未定義 | Null | Null | 変更 | 変更 | |
${hoge:+replace} | ${hoge+replace} | ${hoge:-replace} | ${hoge-replace} |
- コロン付き代替値 :+
空の場合は、代替値を使用しない。 - コロン無し代替値 +
変数が定義済みであれば、空文字でも、代替値を使用する。 - コロン付きデフォルト値 :-
値がある場合は、存在する値を使用する。 - コロン無しデフォルト値 -
変数未定義のみ、デフォルト値を使用する。
#!/bin/bash
hoge="Hello"
# hoge=""
# hoge=""
echo ":+>" ${hoge:+replace} "<"
echo "+ >" ${hoge+replace} "<"
echo ":->" ${hoge:-replace} "<"
echo "- >" ${hoge-replace} "<"
特殊変数
$? コマンドの終了ステータス
$$ プロセス番号
$0 コマンド名
$# 引数の数
$1 1番目の引数
$* 引数全て. "$1 $2 $3 … "
${#array[@]} 配列 array[]の要素数
$ array=(a b c d e f)
$ echo ${array[@]} a b c d e f
$ echo ${#array[@]} 6
$ echo $array a
$ echo ${#array} 1
# arrayの全要素を処理する
for TT in ${array[@]}; do echo $TT ; done
#空白を含むファイル名の展開
$ ls bin/*.txt
bin/hoge hoge.txt
$ for f in bin/*.txt; do echo `basename "$f"` ; done
hoge hoge.txt --- Good
$ for f in bin/*.txt; do echo `basename $f` ; done
hoge ------------ NG