Open7
【メモ】シェルスクリプト
シェルスクリプトの引数をループする
forを使用したサンプル
for arg in "$@"; do
echo "$arg"
done
実行結果
% ./echo-args2.sh abc def ghi
abc
def
ghi
補足
-
$@
: すべての引数を展開する
whileを使用したサンプル
while [ "$#" -gt 0 ]; do
echo "$#" "$1" "$2"
shift
done
実行結果
% ./echo-args.sh abc def ghi
3 abc def
2 def ghi
1 ghi
補足
-
$#
: 位置パラメータの数。スクリプトに渡された引数の数を表す。 -
$1
: シェルスクリプトの第1引数。 -
<数値1> -gt <数値2>
:test ([ ])
コマンドのオプション。<数値1>
が<数値2>
より大きければ真。 -
shift
: 位置パラメータをシフトする。引数でシフト回数を指定できる。- shiftを実行した場合、
$2
が$1
として扱われる。
- shiftを実行した場合、
if文
例
基本構文
if [ <条件1> ]; then
<処理>
elif [ <条件2> ]; then
<処理>
else
<処理>
fi
&& や || を使用
if [ <条件1-1> ] && [ <条件1-2> ]; then
<処理>
elif [ <条件2-1> ] || [ <条件2-2> ]; then
<処理>
else
<処理>
fi
testコマンド ([ ]) の条件演算子
条件式 | 内容 |
---|---|
-z <文字列> |
文字列が空文字列ならば真 |
-n <文字列> |
文字列が空文字列でなければ真 |
<文字列> |
(-n と同じ) |
<文字列1> = <文字列2> |
<文字列1> と<文字列2> が同じならば真 |
<文字列1> != <文字列2> |
<文字列1> と<文字列2> が異なれば真 |
<数値1> -eq <数値2> |
<数値1> と<数値2> が等しければ真 |
<数値1> -ne <数値2> |
<数値1> と<数値2> が等しくなければ真 |
<数値1> -lt <数値2> |
<数値1> が<数値2> より小さければ真 |
<数値1> -le <数値2> |
<数値1> が<数値2> より小さいか等しければ真 |
<数値1> -gt <数値2> |
<数値1> が<数値2> より大きければ真 |
<数値1> -ge <数値2> |
<数値1> が<数値2> より大きいか等しければ真 |
<数値1> -eq <数値2> |
<数値1> と<数値2> が等しければ真 |
<条件式1> -a <条件式2> |
and演算子(非推奨) |
<条件式1> -o <条件式2> |
or演算子(非推奨) |
注意事項
- 各引数はスペースで区切る
- 文字列の比較は
==
ではなく=
で- bashでは
==
も使用可能だが、移植性を重視するなら=
を使用する
- bashでは
- 演算子の
<
>
や(
)
はクォートが必要- 例:
[ "$str" \> paaa ]
- 例:
-
\<
\>
は文字列の比較演算子。数値比較は-lt
-gt
を使用する
参考
シェル変数
特殊パラメータ
パラメータ名 | 内容 |
---|---|
"$@" | 引数すべてをそのまま引き継いで参照する |
$* | 引数すべてを1つに連結して参照する |
$# | 引数の個数 |
$_ | 直前に実行したコマンドの最後の引数 |
変数展開
記法 | 説明 |
---|---|
${#<変数名>} | 変数の値の文字列長 |
${<変数名>#<パターン>} | <変数名>の値の文字列の左側から<パターン>に一致する最短の部分を削除 |
${<変数名>##<パターン>} | <変数名>の値の文字列の左側から<パターン>に一致する最長の部分を削除 |
${<変数名>%<パターン>} | <変数名>の値の文字列の右側から<パターン>に一致する最短の部分を削除 |
${<変数名>%%<パターン>} | <変数名>の値の文字列の右側から<パターン>に一致する最長の部分を削除 |
${<変数名>/<パターン>/<置換文字>} | <変数名>の値の文字列の左側から最初に<パターン>に一致する部分を<置換文字>に置き換える |
${<変数名>//<パターン>/<置換文字>} | <変数名>の値の文字列で<パターン>に一致する部分をすべて<置換文字>に置き換える |
例
${<変数名>#<パターン>}, ${<変数名>%<パターン>}
dir="/usr/local/bin"
echo "${dir#*/}" # "usr/local/bin"
echo "${dir##*/}" # "bin"
echo "${dir%/*}" # "/usr/local"
echo "${dir%%/*}" # ""
オプションフラグ
オプション一覧
オプション | フラグ | 意味 |
---|---|---|
errexit | -e | コマンドの実行失敗時に後続の処理を行わずにスクリプトを終了 |
nounset | -u | 未設定のパラメータ参照時にエラー |
noglob | -f |
* や? によるパス名の展開を行わない |
verbose | -v | コマンド入力時にコマンド入力行をそのまま表示 |
xtrace | -x | コマンド実行時に展開後のコマンド行を表示 |
noexec | -n | 文法チェックのみ行い実行しない |
- | -o | 拡張オプションを有効にする(※) |
pipefail | - | パイプライン中コマンドが一つでもエラーになればパイプを終了する |
- ※:
set -o xtrace
でset -x
と同じ設定を行う- pipefailオプションは
set -o pipefail
で設定する。
- pipefailオプションは
オプション設定方法
setコマンド
- オプションフラグ
でフラグをセット
+ オプションフラグ
でフラグを解除
例: set -x
shebangによる設定
シェルスクリプトの先頭に #!/bin/bash -f
のように記述すると -f
オプションが有効になる
参考
- とほほのBash入門 - とほほのWWW入門
- [改定第3版]シェルスクリプト基本リファレンス P120
複数行の文字列を読み込んでループを回す
ファイルから読み込み
$ cat hoge.txt
hoge hige
fuga figa
piyo poyo
moge mige
while read -r h f; do
echo "$h,$f"
done < hoge.txt
# hoge,hige
# fuga,figa
# piyo,poyo
# moge,mige
ワンライナー
while read -r line; do echo $line; done < /hoge/fuga.txt
補足
-
read -r
でバックスラッシュによるエスケープを防止
ヒヤストリング
<<<
の右側に記述された1つの文字列の内容がコマンドの標準入力にリダイレクトされる。
文字列の終端には自動で改行が付与される。
改行を含む文字列を1行ずつ扱う
スクリプト
text="aaa
bbb
ccc
ddd"
while read -r line; do
echo "line: $line"
done <<< "$text"
実行結果
line: aaa
line: bbb
line: ccc
line: ddd
変数展開との組み合わせ
変数展開を行う場合はヒヤストリングのシングルクオートを一旦閉じてダブルクオートに切り替える
cat <<< 'ヒヤストリングのテストです
$HOMEの値は'"$HOME"'です。
`pwd`は'"`pwd`"'に置換されます。
参考
配列(Bash)
# 宣言
array=("aaa" "bbb" "ccc") # イコールの前後にスペースを入れない
# 参照
echo ${array[0]} # aaa
echo ${array[1]} # bbb
echo ${array[2]} # ccc
echo "${array[*]}" # "aaa bbb ccc"
echo "${array[@]}" # "aaa" "bbb" "ccc"
# 要素数
echo ${#array[*]} # 3
イディオム
スクリプトが配置されているディレクトリを変数に格納
MODULE_DIR=$(cd $(dirname $0); pwd)