プロジェクト

全般

プロフィール

Bashシェルスクリプティング

シェル構文

for文

数値範囲

~$ for value in {0..10}; do echo $value; done
0
1
:
10
~$

~$ for suffix in {01..04}; do echo $suffix; done
01
02
03
04
~$

if文

条件の記述

[]で条件を記述 [[]]で条件を記述
if [ "$x" -gt 0 ]; then
    echo x is plus
fi
if [[ $x -gt 0 ]]; then
    echo x is plus
fi
[]はコマンド
* 変数参照をダブルクォートで囲わないと、変数未定義の時エラー
[[]] は構文

bashでは、[[]] を使う方が応用範囲が広いのでおすすめらしいです。

複数条件
  • if [[ $x -gt 0 && $x -lt 10 ]]; then
    [[]]の中でAND条件(&&)、OR条件(||)を記述できます。

関数

関数の定義と呼び出し

引数がない場合
関数の定義 関数の呼び出し
function foo () {
    echo foo called
}

foo
引数がある場合
関数の定義 関数の呼び出し
function foo () {
    echo foo called with argument $1
}

foo arg1

関数の中では、引数を$1, $2, ... で参照します。
関数の呼び出しでは、関数名の後に、引数を空白区切りで列挙します。

関数の戻り値

数値(0-255)を関数の戻り値として返却することができます。

関数の定義 関数の呼び出し
function foo () {
    return 10
}

foo arg1
echo $?

ファイルに関する操作

パス名からファイル名を取り出し(最後の'/'より以降の文字列)

basename

~$ basename /path/to/alfa.omega
alfa.omega
~$
xargsでbasenameを使用しても意図した振る舞いとならない
~$ ls foo
1.dat 2.dat 3.dat
~$ find foo | xargs basename
1.dat

xargsで複数の引数をbasenameに渡しても、basenameが1つしか引数を取らないためです。
代替手段は、

  • ~$ find foo | awk -F/ '{print $NR}'
  • ~$ find foo -printf '%f\n'

文字列置換

前方一致最長マッチ

~$ f=/path/to/alfa.omega
~$ echo ${f##*/}
alfa.omega
~$

パス名からディレクトリ名を取り出し(最後の'/'の前までの文字列)

dirname

~$ dirname /path/to/alfa.omega
/path/to
~$

文字列置換

後方一致最短マッチ

~$ f=/path/to/alfa.omega
~$ echo ${f%/*}
/path/to
~$

パス名から拡張子を取り出し(最後の'.'より後ろの文字列)

~$ f=/path/to/alfa.omega
~$ echo ${f##*.}
omega
~$

パス名から拡張子を除いたファイル名(基底名)を取り出し

~$ f=/path/to/alfa.omega
~$ basename $f .omega
alfa
~$

ファイルの存在

実行可能なファイルの存在

[[ -x file ]]

ファイルの存在(ディレクトリは除外)

[[ -f file ]]

ディレクトリの存在

[[ -d directory ]]

ファイルまたはディレクトリの存在

[[ -e path ]]

ディレクトリ操作

実行スクリプトのディレクトリを取得

$(cd $(dirname $0); pwd)
  • サブシェルで実行するので、続くシェルスクリプトのカレントディレクトリは元のまま

ディレクトリの存在を確認

if [[ -d $dir ]]; then
    echo "$dir is a directory." 
else
    echo "$dir is NOT a directory." 
fi

コマンドライン

コマンドライン引数の取り込み

コマンドライン引数は、$1, $2, ... に格納されます。
コマンドライン引数が幾つ渡されたかを確認するには、$# を参照します。

if [[ $# != 2 ]]; then
    echo Usage: $0 <src> <dst>
    exit 1
fi

cp -p $1 $2

権限

実行権限

root権限で実行されているかを判定

  if [[ ${EUID}:-${UID}} != 0 ]]; then
    echo "root accessibility is required for running this script" 
  fi

参考文献

ブログ

bashスクリプトのベストプラクティスを調査した


3ヶ月前に更新