![見出し画像](https://assets.st-note.com/production/uploads/images/168008653/rectangle_large_type_2_a56b768299d07d262d0d1df9bd750a53.png?width=1200)
bashの記述を見直そう!
はじめに
Software Design 2024年12月号の特集「シェルスクリプトの基本と罠」を読んでいたのですが、シェルの記述方式をちゃんと理解していないことに気づきまして、改めて勉強し直そうと各種記述を以下にまとめました。
特殊パラメータ
$0: シェルスクリプト名
サンプル
#!/bin/bash
echo '$0:' $0
結果
~/bash$ ./sample_args.sh a1 a2 a3
$0: ./sample_args.sh
$1~9: シェルスクリプトに渡される引数
サンプル:10以降の引数は${10}のように波括弧を付けて表現します。
#!/bin/bash
echo '$1:' $1
結果
~/bash$ ./sample_args.sh a1 a2 a3
$1: a1
$*: シェルスクリプトに渡される引数全て
サンプル
#!/bin/bash
echo '$*:' $*
for arg in "$*";do echo $arg; done;
結果:$*は引数がひとまとまりとして扱われます。
~/bash$ ./sample_args.sh a1 a2 a3
$*: a1 a2 a3
a1 a2 a3
$@: シェルスクリプトに渡される引数全て
サンプル
#!/bin/bash
echo '$@:' $@
for arg in "$@";do echo $arg; done;
結果:$@は引数が別々に扱われます。
~/bash$ ./sample_args.sh a1 a2 a3
$@: a1 a2 a3
a1
a2
a3
$#: シェルスクリプトに渡される引数の数
サンプル
#!/bin/bash
echo '$#:' $#
結果
~/bash$ ./sample_args.sh a1 a2 a3
$#: 3
$?: 最後に実行したコマンドの終了ステータス
サンプル
#!/bin/bash
echo '$?:' $?
結果:echoの正常終了ステータスなので0
~/bash$ ./sample_args.sh a1 a2 a3
$?: 0
$$: シェルスクリプトのPID
サンプル
#!/bin/bash
echo '$$:' $$
結果
~/bash$ ./sample_args.sh a1 a2 a3
$$: 50666
パラメータの展開
${parameter:-word} parameterが未設定であればwordを使用。parameterへの代入はなし
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo '${parameter:-word}:' echo ${parameter:-word}
echo 'parameter:' $parameter
unset parameter
echo '${parameter:-word}:' echo ${parameter:-word}
echo 'parameter:' $parameter
結果
~/bash$ ./sample_param.sh
${parameter:-word}: echo word-parameter-word
parameter: word-parameter-word
${parameter:-word}: echo word
parameter:
${parameter:=word} parameterが未設定であればwordを使用。parameterへの代入あり
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo '${parameter:=word}:' echo ${parameter:=word}
echo 'parameter:' $parameter
unset parameter
echo '${parameter:=word}:' echo ${parameter:=word}
echo 'parameter:' $parameter
結果
~/bash$ ./sample_param.sh
${parameter:=word}: echo word-parameter-word
parameter: word-parameter-word
${parameter:=word}: echo word
parameter: word
${parameter:+word} parameterが設定されていればwordを使用。未設定であれば空文字。parameterへの代入あり【注意!】
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo 'parameter:' $parameter
echo '${parameter:+word}:' echo ${parameter:+word}
unset parameter
echo '${parameter:+word}:' echo ${parameter:+word}
echo 'parameter:' $parameter
結果:なお":+"は本来parameterへの代入があるとのことですが、実施したwsl2だと正しく代入されません。実行環境によって違うのかも知れませんので、使用時はご注意ください。
~/bash$ ./sample_param.sh
parameter: word-parameter-word
${parameter:+word}: echo word
${parameter:+word}: echo
parameter:
${parameter+word} parameterが未設定であればwordを使用。未設定であれば空文字。parameterへの代入なし
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo 'parameter:' $parameter
echo '${parameter+word}:' echo ${parameter+word}
unset parameter
echo '${parameter+word}:' echo ${parameter+word}
echo 'parameter:' $parameter
結果
parameter: word-parameter-word
${parameter+word}: echo word
parameter: word-parameter-word
${parameter+word}: echo
parameter:
${parameter:?word} parameterが未設定であればwordをエラーとして出力
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo 'parameter:' $parameter
echo '${parameter:?word}:' echo ${parameter:?word}
unset parameter
echo '${parameter:?word}:' echo ${parameter:?word}
結果:unsetしてparameterを未設定にするとエラーが発生します。また"$?"も終了ステータスが1になります。
parameter: word-parameter-word
${parameter:?word}: echo word-parameter-word
./sample_param.sh: line 40: parameter: word
~/bash$ echo $?
1
${parameter%word} 最短一致した接尾辞のパターンを削除する
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo '${parameter%word}:' echo ${parameter%word}
結果
~/bash$ ./sample_replace.sh
${parameter%word}: echo word-parameter-
${parameter#word} 最短一致した接頭辞のパターンを削除する
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo '${parameter#word}:' echo ${parameter#word}
結果
~/bash$ ./sample_replace.sh
${parameter#word}: echo -parameter-word
${parameter#offset} parameterからoffset(0始まり)以降の文字列を抜き出す
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo '${parameter#offset}:' echo ${parameter#6}
結果
~/bash$ ./sample_replace.sh
${parameter#offset}: echo word-parameter-word
${#parameter} parameterの文字数をカウント
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo '${#parameter}:' echo ${#parameter}
結果
~/bash$ ./sample_replace.sh
${#parameter}: echo 19
${#parameter/pattern/string} parameterでpatternにマッチした部分をstringに置換 (1回のみ)
サンプル
#!/bin/bash
export parameter="word-parameter-word"
echo '${#parameter/pattern/string}:' echo ${parameter/a/A}
結果
~/bash$ ./sample_replace.sh
${#parameter/pattern/string}: echo word-pArameter-word
${#parameter//pattern/string} parameterでpatternにマッチした部分をstringに置換 (全て)
サンプル:"[ ]"でorは実現できますが、正規表現自体は使用不可みたいです。
#!/bin/bash
export parameter="word-parameter-word"
echo '${#parameter//pattern/string}:' echo ${parameter//[ao]/X}
結果
~/bash$ ./sample_replace.sh
${#parameter//pattern/string}: echo wXrd-pXrXmeter-wXrd
if文のオプション
equal判定
サンプル
#!/bin/bash
export parameter="sample"
if [ ${parameter} = "sample" ]; then
echo "equalでture"
fi
結果
equalでture
not equal判定
サンプル
#!/bin/bash
export parameter="sample"
if [ ${parameter} != "sample2" ]; then
echo "not equalでture"
fi
結果
not equalでture
文字列長が 大なら true
サンプル
#!/bin/bash
export parameter="sample"
if [ -n ${parameter} ]; then
echo "文字列長が 大なら true"
fi
結果
文字列長が 大なら true
文字列長が 0 なら true
サンプル
#!/bin/bash
export parameter=""
if [ -z ${parameter} ]; then
echo "文字列長が 0 なら true"
fi
結果
文字列長が 0 なら true
ファイルとディレクトリの判定:ファイル-f/ディレクトリ-d/存在有無-e/サイズ-s/読み-r/書き-w/実行-x/による判定
ファイル(sample.txt)とディレクトリ(sample)を以下のように用意しています。
~/bash$ ls -l
drwxr-xr-x 2 sample sample 4096 Dec 31 15:34 sample
-rw-r--r-- 1 sample sample 6 Dec 31 15:41 sample.txt
サンプル
#!/bin/bash
export file="sample.txt"
if [ -f ${file} ]; then
echo "${file} がファイルなら true"
fi
if [ ! -d ${file} ]; then
echo "${file} がディレクトリでないなら true"
fi
if [ -e ${file} ]; then
echo "${file} が存在するなら true"
fi
if [ -s ${file} ]; then
echo "${file} のサイズが 0 より大きければ"
fi
if [ -r ${file} ]; then
echo "${file} が読み取り可能なら true"
fi
if [ -w ${file} ]; then
echo "${file} が書き込み可能なら true"
fi
if [ ! -x ${file} ]; then
echo "${file} が実行可能でないなら true"
fi
export dir="sample"
if [ ! -f ${dir} ]; then
echo "${dir} がファイルでないなら true"
fi
if [ -d ${dir} ]; then
echo "${dir} がディレクトリなら true"
fi
if [ -s ${dir} ]; then
echo "${dir} のサイズが 0 より大きければ"
fi
if [ -e ${dir} ]; then
echo "${dir} が存在するなら true"
fi
if [ -r ${dir} ]; then
echo "${dir} が読み取り可能なら true"
fi
if [ -w ${dir} ]; then
echo "${dir} が書き込み可能なら true"
fi
if [ -x ${dir} ]; then
echo "${dir} が実行可能なら true"
fi
結果
sample.txt がファイルなら true
sample.txt がディレクトリでないなら true
sample.txt が存在するなら true
sample.txt のサイズが 0 より大きければ
sample.txt が読み取り可能なら true
sample.txt が書き込み可能なら true
sample.txt が実行可能でないなら true
sample がファイルでないなら true
sample がディレクトリなら true
sample のサイズが 0 より大きければ
sample が存在するなら true
sample が読み取り可能なら true
sample が書き込み可能なら true
sample が実行可能なら true
参考
参考サイトを以下に記載します。
[Bash]特殊変数とパラメータ展開
【シェルスクリプトBash】 if 文(test文)のオプションまとめ