【Linux】Bash shell

この記事はブログとプログラミングで生計をたてている海外在住ウェブディベロッパーがわかりやすさにこだわって作成しました

変数
変数の宣言

declare(typeset)

変数を明示的に宣言してから使用します。この場合はいろいろな属性を与えることができるようになります。

  • -a 変数を配列とする
  • -f 変数を関数とする
  • -i 変数を数値とする。
  • -r 変数を読み出し専用とする。
  • -x 変数をエクスポートする。
  • -p 変数の値を表示する。

readonly

変数を読み出し専用として使用する場合はreadonlyを使用して変数を宣言すると便利です

local

bashスクリプトで使用される変数は基本的にすべてグローバル変数です。
関数内だけで変数を使用したい場合はlocalで変数を宣言すると、関数内で有効なローカル変数を使用できます。

特別な変数

特別な変数

シェルスクリプトが引数を得る場合、$1, $2 といった特別な変数を利用することができる。この変数は、$0 〜 $9 までしか使えない。それ以上引数があり、順番に取得したいなら shift を利用する。

$0スクリプト名
$1 〜 $9引数1番目から9番目
$*すべての引数("$*"とした場合、"$1 $2 …"のように展開)
$@すべての引数(ダブルクォートで囲んだ場合の処理が $* と異なり個別に引用される)
$#引数の数

サンプルで見てみよう

#!/bin/sh
 
echo "script name: $0"
echo "arg num : $#"
echo "arg 1   : $1"
echo "arg 2   : $2"
echo "arg 3   : $3"
echo "arg 4   : $4"
echo "arg 5   : $5"
echo "arg 6   : $6"
echo "arg 7   : $7"
echo "arg 8   : $8"
echo "arg 9   : $9"
echo "arg 10? : $10"
echo "all arg : $*"
exit 0

を実行すると以下のように $9 まで展開されていることがわかる

$ ./cmd.sh a b c d e f g h i j k l
script name: ./cmd.sh
arg num : 12
arg 1   : a
arg 2   : b
arg 3   : c
arg 4   : d
arg 5   : e
arg 6   : f
arg 7   : g
arg 8   : h
arg 9   : i
arg 10? : a0
all arg : a b c d e f g h i j k l
$

このほかに以下のようなものがある。

$?直前に実行したコマンドのexit値
$$シェル自身のプロセスID
$-シェルの起動時のフラグの一覧
$!シェルが最後に起動したバックグラウンドプロセスのプロセスID

また、環境変数などは、特別な処理でない限り変数として利用するのは避けたほうがよい(使ってはいけない)。

PATHシェルが実行可能なコマンドを検索するディレクトリを指定。ピリオドがカレントディレクトリを意味するが、設定はしないほうがよい。明確にカレントディレクトリのコマンドを実行する場合、./script.sh という具合に実行するほうが確実に意図したスクリプトやコマンドが実行できる。
IFS区切り文字として扱う文字を指定。

基本的には、シェル上で引数なしのsetを実行した際に表示される環境変数(PATH, USER, UID, PRINTER, TERM, TZ,etc.)をローカル変数として利用するのは避けたほうがよい。

準変数

変数を参照する際に、変数がNULLであった場合の評価を設定することができます。

${VAR:-expression}値がセットされていない(NULL)場合、:-以降の式を評価結果を返す。
${VAR:+expression}値がセットされている(NONE-NULL)場合、:+以降の式を評価結果を返す。
${VAR:=expression}値がセットされていない(NULL)場合、:=以降の式を評価結果を返し変数に代入。
${VAR:?[expression]}値がセットされていない(NULL)場合、式が標準エラーに出力。

サンプルで見てみよう

#!/bin/sh
 
echo "[ null variable ]"
VAR=
EXPAND=${VAR:-blue}
echo "-var    : $VAR"
echo "-expand : $EXPAND"
EXPAND=${VAR:+yellow}
echo "+var    : $VAR"
echo "+expand : $EXPAND"
EXPAND=${VAR:=green}
echo "=var    : $VAR"
echo "=expand : $EXPAND"
echo ""
echo "[ non-null variable ]"
VAR=red
EXPAND=${VAR:-blue}
echo "-var    : $VAR"
echo "-expand : $EXPAND"
EXPAND=${VAR:+yellow}
echo "+var    : $VAR"
echo "+expand : $EXPAND"
EXPAND=${VAR:=green}
echo "=var    : $VAR"
echo "=expand : $EXPAND"
exit 0

を実行すると以下のように評価されます。

$ ./var.sh
[ null variable ]
-var    :
-expand : blue
+var    :
+expand :
=var    : green
=expand : green
 
[ non-null variable ]
-var    : red
-expand : red
+var    : red
+expand : yellow
=var    : red
=expand : red
$

特殊文字

以下の文字は特殊文字として扱われます

; | & ^ $ ? * < > ( ) [ ] { } ` " ' TAB SPACE NEWLINE

これら特殊文字を表示するには、エスケープする必要があります。エスケープの方法は、バックスラッシュを利用して一文字単位で行うか、シングルクオーテーションで囲むことで行えます。ダブルクオーテーションで囲んだ場合、$ ` \ は評価されます。つまり、変数やコマンドは処理されます。

*ZERO またはすべての文字にマッチします。また、引数で利用した場合、すべてのファイル名を展開
?一文字にマッチ
[range]文字範囲にマッチ
\特殊文字をエスケープ
' '囲まれたすべてを文字列として扱う
" "$ ` \ を評価し囲まれたすべてを文字列として扱う
` `コマンドを評価
条件分岐と条件式
if文

if-fi

条件が満たされる場合のみ処理をする

if-else-fi

条件が満たされる場合と満たされない場合それぞれ別の処理をする

if-elif-else-fi

条件ごとにそれぞれ別の処理をする。

条件式
bashの条件式はtestコマンドを使用します。test コマンドは与えられた2つの数値を比較し、それらの等価・大小を評価することができます。また比較条件は実行時に指定されたオプションにより決定される。(オプションは以下参照)
testコマンドは略式の [] を使用して記述することができます。test コマンドの引数をそのまま [] の中に記述します。
※ただし、[ の直後と ] の直前には必ず半角スペースが必要となります
[__su_spoiler title=”数値” open=”yes” style=”fancy”]
  • 数値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より大きいか同じであれば真を返す
[__/su_spoiler] [__su_spoiler title=”文字列” open=”yes” style=”fancy”]
  • 文字列,-n 文字列 指定した文字列が1文字以上であれば真を返す
  • -z 文字列 指定した文字列が0文字(何もない)状態であれば真を返す
  • 文字列1 = 文字列2 文字列1と文字列2が同じであれば真を返す
  • 文字列1 != 文字列2 文字列1と文字列2が違ければ真を返す
[__/su_spoiler] [__su_spoiler title=”ファイル” open=”yes” style=”fancy”]
  • -G ファイル 指定したファイルが存在し,ファイルのグループが現在実行しているユーザーであれば真を返す
  • -O ファイル 指定したファイルが存在し,ファイルの所有者が現在実行しているユーザーであれば真を返す
  • -S ファイル 指定したファイルが存在し,ソケットであれば真を返す
  • -b ファイル 指定したファイルが存在し,ブロック・デバイスであれば真を返す
  • -c ファイル 指定したファイルが存在し,キャラクタ・スペシャル・ファイルであれば真を返す
  • -d ファイル 指定したファイルが存在し,ディレクトリであれば真を返す
  • -e ファイル 指定したファイルが存在すれば真を返す
  • -f ファイル 指定したファイルが存在し,通常のファイルであれば真を返す
  • -g ファイル 指定したファイルが存在し,パーミッションにセット・グループIDが付いていれば真を返す
  • -h ファイル,-L ファイル 指定したファイルが存在し,シンボリック・リンクであれば真を返す
  • -k ファイル 指定したファイルが存在し,パーミッションにスティッキ・ビットが付いていれば真を返す
  • -p ファイル 指定したファイルが存在し,名前付きパイプであれば真を返す
  • -r ファイル 指定したファイルが存在し,読み取り可能であれば真を返す
  • -s ファイル 指定したファイルが存在し,ファイル・サイズが1以上であれば真を返す
  • -t ファイル 指定したファイルが端末でオープンされていれば真を返す
  • -u ファイル 指定したファイルが存在し,パーミッションにセット・ユーザーIDが付いていれば真を返す
  • -w ファイル 指定したファイルが存在し,書き込み可能であれば真を返す
  • -x ファイル 指定したファイルが存在し,実行可能であれば真を返す
  • ファイル1 -nt ファイル2 指定したファイル1がファイル2より修正時刻が新しければ真を返す
  • ファイル1 -ot ファイル2 指定したファイル1がファイル2より修正時刻が古ければ真を返す
  • ファイル1 -ef ファイル2 指定したファイル1とファイル2のデバイス番号とiノード番号が同じであれば真を返す
[__/su_spoiler] [__su_spoiler title=”条件式の論理演算” open=”yes” style=”fancy”]
  • ! 条件式 条件式が偽であれば真を返す
  • 条件式1 -a 条件式2 条件式1と条件式2の結果が共に真であれば真を返す(論理積)
  • 条件式1 -o 条件式2 条件式1または条件式2の結果のいずれかが真であれば真を返す(論理和)
  • 文字列1 != 文字列2 文字列1と文字列2が違ければ真を返す
論理積(-a)は「&&」で、論理和(-o)は「||」で置き換えることができます
ただし、使用方法が若干異なります。次の使用例を参照ください

-aを使用した条件式

!/bin/bash
LOCK_FILE="lock"
DIR="dir"
if [ -f ${LOCK_FILE} -a -d ${DIR} ]; then
  echo "ファイルとディレクトリが存在します"
else
  echo "ファイルかディレクトリのいずれかが存在しません"
fi

&&を使用した条件式

!/bin/bash
LOCK_FILE="lock"
DIR="dir"
if [ -f ${LOCK_FILE} ] && [ -d ${DIR} ]; then
  echo "ファイルとディレクトリが存在します"
else
  echo "ファイルかディレクトリのいずれかが存在しません"
fi
[__/su_spoiler]

参考

IF文やTESTコマンドはこちらを参考にしました。
if 文と test コマンド | UNIX & Linux コマンド・シェルスクリプト リファレンス
if 文と test コマンド if 文とは? if 文とは、与えられた条件式が真のときのみ処理を行い、それ以外の場合は処理をスキップする、などといった場合に使用される条件分岐処理である。 条件式には一般的に test コマンドを用いるが、ls コマンドや grep コマンド等の他のコマンドを用いても構わない。 if ...
BASH変数の文字列抽出はこちらのサイトが参考になります。
bashで変数から部分文字列を取得する - Qiita
bashで変数から部分文字列を取得する方法まとめ パラメータ展開を利用して部分文字列を取得する オフセットと長さを指定して文字列を取得する 指定方法 ${パラメータ:オフセット:長さ} 部分文字列抽出 #!/bin...
PHP/Javascript/WORDPRESS案件全般承ります

オーストラリアで主に日系企業や個人のお客様からのご依頼でお仕事をしております。この記事についてのご質問またはお困りのことがございましたら、お気軽にお問い合わせください。

タイトルとURLをコピーしました