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 として扱われる。
あぷしあぷし

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では == も使用可能だが、移植性を重視するなら = を使用する
  • 演算子の < >( ) はクォートが必要
    • 例: [ "$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 xtraceset -xと同じ設定を行う
    • pipefailオプションは set -o pipefail で設定する。

オプション設定方法

setコマンド

- オプションフラグ でフラグをセット
+ オプションフラグ でフラグを解除

例: set -x

shebangによる設定

シェルスクリプトの先頭に #!/bin/bash -f のように記述すると -f オプションが有効になる

参考

あぷしあぷし

複数行の文字列を読み込んでループを回す

ファイルから読み込み

$ 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)