値が整数であるかどうか確認する。
成果物
結論
IsInt() { test 0 -eq $1 > /dev/null 2>&1 || expr $1 + 0 > /dev/null 2>&1; }
よく見かける
exprだけの奴はバグがある。
ネット上では以下コードで数値判定できるような記事を見かける。
IsInt() { expr $1 - 1 > /dev/null 2>&1; }
 しかし、-1のときfalseになってしまうバグがある。
$ IsInt -1 && echo 'Int' || echo 'NotInt' NotInt
 それ以外の整数値なら負数であってもtrueになる。
$ IsInt -2 && echo 'Int' || echo 'NotInt' Int
 原因は、expr -1 + 1が0になりfalseとなってしまうため。
対策
 対策は、計算結果が0になる場合の入力値のみ個別に判定すること。
IsInt() { test -1 -eq $1 || expr $1 + 1 > /dev/null 2>&1; }
 testで数値比較できない値が入るとエラー文言が出力されてしまう。それを> /dev/null 2>&1で消す。
IsInt() { test -1 -eq $1 > /dev/null 2>&1 || expr $1 + 1 > /dev/null 2>&1; }
 expr $1 + 1すると最大値が使えなくなってしまう。妥協案としてexpr $1 - 1に変更して最小値を使えないようにする。計算結果が0になる値の個別チェックもこれに伴い変更する。
IsInt() { test 1 -eq $1 > /dev/null 2>&1 || expr $1 - 1 > /dev/null 2>&1; }
 最大値、最小値、どちらも使えるようにしたい。そこでexpr $1 + 0とした。(expr $1 + 1でもexpr $1 - 1でもなく) 計算結果が0になる値の個別チェックもこれに伴い変更する。
IsInt() { test 0 -eq $1 > /dev/null 2>&1 || expr $1 + 0 > /dev/null 2>&1; }
以上。
使い方
 true。
IsInt 0 && echo 'Int' || echo 'NotInt' IsInt 1 && echo 'Int' || echo 'NotInt' IsInt 2 && echo 'Int' || echo 'NotInt' IsInt -1 && echo 'Int' || echo 'NotInt' IsInt -2 && echo 'Int' || echo 'NotInt' IsInt 9223372036854775807 && echo 'Int' || echo 'NotInt' IsInt -9223372036854775807 && echo 'Int' || echo 'NotInt'
 false。
IsInt A && echo 'Int' || echo 'NotInt' IsInt 0.1 && echo 'Int' || echo 'NotInt' IsInt 9223372036854775808 && echo 'Int' || echo 'NotInt' IsInt -9223372036854775808 && echo 'Int' || echo 'NotInt'
最大値:9223372036854775807
$ expr 9223372036854775807 + 1 expr: +: 計算結果は範囲外の値です $ expr 9223372036854775806 + 1 9223372036854775807
最小値:-9223372036854775808
$ expr -9223372036854775808 - 1 expr: -: 計算結果は範囲外の値です $ expr -9223372036854775807 - 1 -9223372036854775808
問題
- 最小値〜最大値の範囲外はたとえ整数値であってもfalseになる
- 浮動小数は対象外(falseになる)
最小値〜最大値の範囲外はたとえ整数値であってもfalseになる
仕方ない。Bash言語仕様の限界。
浮動小数は対象外(falseになる)
IsInt 0.1 && echo 'Int' || echo 'NotInt' # NotInt
 IsIntに浮動小数を渡せばfalseが返る。
 Bashでは浮動小数を扱えない。整数のみ。bcコマンドで扱えるが、Raspbianにはデフォルトでインストールされていない。また、.1のように最初の0を省略せねばならないなどのクセがある。
対象環境
- Raspbierry pi 4 Model B
- Raspbian buster 10.0 2019-09-26 ※
- bash 5.0.3(1)-release
$ uname -a Linux raspberrypi 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux