Paepoi » ShellScript Tips » ShellScript Tips | 条件分岐
ShellScript Tips | 条件分岐
# 最終更新日 2019.12.01
更に bash, zsh では [[...]] も使える、この三つは下記のような場合はまったく同じです。
[[...]] はいったい何かというと [ の拡張と思えばいいようです。
上記で既に書いていますが単純な if 文であれば &&, || のほうが簡単かつ明解です。
[[ 条件式 ]] && 真の場合 || 偽の場合
ブレースでネストすることもできる。
ただし以下のような場合があるので注意。
上記のようにブレースはブロックスコープにならないので必ず or 演算もセットで使う。
何もしないならコロンを使うのが一番簡単。
elif を使う場合は素直に if を使ってください。
以下は条件式。
数値
文字列
ファイル
以上がありますがほとんど引数のことですね。
こんなふうに使います。
また条件を「|」記号で or 演算することもできる。
ただし C 言語の関数等と違い別プロセスとして実行されます。
親シェルの変数は参照できますが戻り値は $? を利用します。
関数の呼び出しに括弧は不要で引数は半角空白区切りで渡します。
関数側から引数を参照するには $1, $2... を利用、別プロセスなのでスクリプトの呼び出し引数とは違う。
等々、C 言語なんかを知っていると少し戸惑ってしまうと思います。
UNIX のコマンドが全部そうなっていることに気が付いたかな。
test コマンドと [[
test コマンドは真偽値を戻す、代わりに [...] を利用することもできる。更に bash, zsh では [[...]] も使える、この三つは下記のような場合はまったく同じです。
if test 1 -ne 2; then # ↓ if [ 1 -ne 2 ]; then # ↓ if [[ 1 -ne 2 ]]; then
[[...]] はいったい何かというと [ の拡張と思えばいいようです。
#!/bin/sh # = でパターンマッチ [[ おまえはアホ = *アホ ]] && echo 1 || echo 2 #=> 1 [[ おまえはスケベ = *アホ ]] && echo 1 || echo 2 #=> 2 # =~ で正規表現マッチ、単なる文字列探しにも使える [[ おまえはアホ =~ [(アホ|バカ)] ]] && echo 1 || echo 2 #=> 1 [[ おまえはスケベ =~ [(アホ|バカ)] ]] && echo 1 || echo 2 #=> 2 # 辞書順で文字列比較、数値優先には当然ならないけど [[ test2.txt < test12.text ]] && echo 1 || echo 2 #=> 2 # 論理演算子が &&, || になる [[ a = a && b = b ]] && echo 1 #=> 1
if
if については説明不要かと。上記で既に書いていますが単純な if 文であれば &&, || のほうが簡単かつ明解です。
[[ 条件式 ]] && 真の場合 || 偽の場合
if [[ $PWD = $HOME ]]; then echo ホームです else cd ~ fi # ↓ [[ $PWD = $HOME ]] && echo ホームです || cd ~
ブレースでネストすることもできる。
ただし以下のような場合があるので注意。
#!/bin/sh motor=スズキのバイクはかっこいい [[ $motor =~ スズキ ]] && { [[ $motor =~ かっこいい ]] && echo ヨシ! [[ $motor =~ かっこわるい ]] && echo シネ! } || { echo ダセーwwwww }ダセーwwwwwも表示されてしまうはずです。
上記のようにブレースはブロックスコープにならないので必ず or 演算もセットで使う。
何もしないならコロンを使うのが一番簡単。
[[ $motor =~ かっこわるい ]] && echo シネ! || :
elif を使う場合は素直に if を使ってください。
以下は条件式。
数値
条件式 | 意味 |
---|---|
数値 -eq 数値 | == |
数値 -ne 数値 | != |
数値 -ge 数値 | >= |
数値 -gt 数値 | > |
数値 -le 数値 | <= |
数値 -lt 数値 | < |
条件式 | 意味 |
---|---|
-n 文字列 | 文字列が一文字以上ある |
-z 文字列 | 文字列がゼロ文字 |
文字列1 = 文字列2 | 等しい |
文字列1 != 文字列2 | 等しくない |
条件式 | 意味 |
---|---|
-G ファイル名 | ファイルのグループが実行ユーザー |
-O ファイル名 | ファイルの所有者が実行ユーザー |
-S ファイル名 | ソケット |
-b ファイル名 | ブロックデバイスファイル |
-c ファイル名 | キャラクタデバイスファイル |
-d ファイル名 | ディレクトリ |
-e ファイル名 | 存在確認 |
-f ファイル名 | 通常ファイル |
-g ファイル名 | SGID がある |
-h ファイル名, -L ファイル名 | シンボリックリンク |
-k ファイル名 | スティッキービットがある |
-p ファイル名 | 名前付きパイプ |
-r ファイル名 | 読み取り可能 |
-s ファイル名 | ファイルサイズがゼロではない |
-t ファイル名 | 端末でオープンされてい |
-u ファイル名 | SUID がある |
-w ファイル名 | 書き込み可能 |
-x ファイル名 | 実行可能 |
ファイル名1 -nt ファイル名2 | ファイル名1のほうが修正時刻が新しい |
ファイル名1 -ot ファイル名2 | ファイル名1のほうが修正時刻が古い |
ファイル名1 -ef ファイル名2 | デバイス番号と i ノード番号が同じ |
特殊変数
特殊変数 | 解説 |
---|---|
$n (数字) | $0 はスクリプト名、以降 $1, $2…${10}, ${11}… と引数が並ぶ |
$# | 引数の個数 |
$@ | $0 以外の全ての引数("$@" の場合 "$1" "$2" …") |
$* | $0 以外の全ての引数("$*" の場合 "$1 $2 …") |
$? | 最後に実行したコマンドの終了ステータス |
$! | 最後に実行したバックグラウンドコマンドの PID |
$$ | シェルの PID |
$- | 現在のオプションフラグ |
以上がありますがほとんど引数のことですね。
こんなふうに使います。
#!/bin/sh echo ディレクトリ名で圧縮します if [[ $# -eq 0 ]]; then echo 引数が無いよ else path=`pwd` name=${path##*/} file-roller --add-to="${name}.tar.gz" "$@" fi
case
case 文は文字列が条件に一致するかで分岐する。条件 | 意味 |
---|---|
? | 一文字 |
* | ワイルドカード |
[...] | [...] に含まれる一文字 |
[!...] | [!...] に含まれない一文字 |
#!/bin/sh case $USER in root|syacho) echo おはようございます ;; sasakima-nao) echo おまえかよ ;; bite-*) echo うぃーす ;; *) echo 誰だヨ! ;; esac
関数
シェルスクリプトも関数が作れます。ただし C 言語の関数等と違い別プロセスとして実行されます。
親シェルの変数は参照できますが戻り値は $? を利用します。
関数の呼び出しに括弧は不要で引数は半角空白区切りで渡します。
関数側から引数を参照するには $1, $2... を利用、別プロセスなのでスクリプトの呼び出し引数とは違う。
等々、C 言語なんかを知っていると少し戸惑ってしまうと思います。
#!/bin/sh your_motor_cycle() { if [[ $1 = スズキ ]]; then owner_var=かっこいい # 親の変数を参照できる return 0 fi return 1 } owner_var=ダサい! # 関数呼び出し、引数は ISF 区切りで渡す your_motor_cycle スズキ # if test func みたいにできない [[ $? ]] && echo $owner_var || echo 失敗どうしても戻り値が欲しいならパイプを使う。
UNIX のコマンドが全部そうなっていることに気が付いたかな。
#!/bin/sh suzuki() { echo $1カッコイイ return 0 } suzuki スズキのバイクは | cat -n # 変数に入れたい場合 car=`suzuki 車も` echo スズキは$car
Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.