
Bashでゼロ除算エラーを無視する方法は?
例 1: (動作しない)
echo $((1/0)); echo "yay";
echo $((1/0)) || echo "yay";
例2:
echo -n $(echo -n $((1/0))) 2> /dev/null; echo "yay";
0で除算する場合、特定の値をデフォルトとして使用する例2よりも簡単な方法はありますか?
答え1
Bashにはゼロで除算する方法はなく、ash、ksh93、pdksh、zshも同様です。ゼロで除算する唯一の方法は、除算が発生する前に検出するか(除算を実行する前に各分母を確認する)、サブシェルで除算を実行することです。
サブシェルで算術演算を実行している場合は、サブシェルの終了状態を使用してエラーが発生したかどうかを確認できます(ゼロまたは他のエラーに分割)。
x=$(echo $(($a/$b)))
if [ $? -ne 0 ]; then
echo "$b is 0 or some other arithmetic error occurred"
fi
答え2
まあ、if (($divisor == 0)); then SHUT_DOWN_EVERYTHING;
私の考えではサブシェルを使うことができると思います。
(echo $((1/0))) 2>/dev/null || echo yay
しかし、これは要求された「デフォルト」ではなくサンプルコードのエラーを自動的に無視するので、何をしようとしているのか説明しませんか?
答え3
SIGFPE(信号番号8)は、おそらくここでキャッチする必要がある信号です。
このシグナル用のシグナルハンドラを取り付けます。
trap "echo divide by zero >&2 ; exit 1 " SIGFPE
更新:bashにはオーバーライドできない独自のハンドラがあるようです。ソリューションを通常のCプログラムからbash構文に移動しました。
うーん - この方法は他のトラップでも機能します。
答え4
私たちはスクリプトで小さな機能を使用します
#!/bin/sh
divisor_valid "$myvar" || myvar=1
x=$(( 1000 / myvar ))
y=$(( 1000 % myvar ))
これにより、まだ読みやすくなり、CPU集約的なサブシェルを回避できます。
ヘルパー機能は次のとおりです。
isnumber(){ test 2>/dev/null ${1:-a} -eq "${1##*[!0-9-]*}";}
divisor_valid(){ isnumber $1||return;case $1 in 0|-0)false;;esac;}
busybox-ashを使用していますが、POSIX(tm)でも動作します。