Как обрабатывать ошибки с помощью арифметических операций Bash? - PullRequest
2 голосов
/ 14 марта 2019

Есть ли способ обработки ошибок с помощью арифметических операций Bash?Например, попытка операции с плавающей запятой, которая не поддерживается, приводит к ошибке:

$ echo $(( 3.5 + 1))
-bash: 3.5 + 1: syntax error: invalid arithmetic operator (error token is ".5 + 1")

Мои попытки обойти ошибку либо с помощью логического ИЛИ, либо путем простого отключения вывода не дают никакой разницы:

$ echo $(( 3.5 + 1)) ||true
-bash: 3.5 + 1: syntax error: invalid arithmetic operator (error token is ".5 + 1")
$ echo $(( 3.5 + 1)) 2>&-
-bash: 3.5 + 1: syntax error: invalid arithmetic operator (error token is ".5 + 1")

Я вижу, как оба механизма отката на самом деле применяются к echo вместо самой арифметической операции, и что именно последний выдает ошибку.

Есть ли способ написать тот или иной, чтобы они применимы к арифметической операции?

Ответы [ 2 ]

1 голос
/ 14 марта 2019

Если целью является просто сбросить сообщение об ошибке, то естественный способ попытаться это сделать -

echo $(( 3.5 + 1)) 2>/dev/null

К сожалению, это не работает. Я думаю, это потому, что сообщение об ошибке исходит от самого Bash. Однако это работает (по крайней мере, на Bash 4.2):

( echo $(( 3.5 + 1)) ) 2>/dev/null

(...) создает подоболочку, которая является очень дорогой на некоторых платформах (в частности, Cygwin и WSL). Этот немного более грязный код также работает и не создает подоболочки:

{ echo $(( 3.5 + 1)) ; } 2>/dev/null
1 голос
/ 14 марта 2019

Если ваши выражения никогда не оцениваются в 0, вы можете использовать

((var=expr)) 2>&- && echo "$var"

Некоторые примеры:

prompt$ ((var =3+1)) 2>&- && echo "$var"
4
prompt$ ((var=3+1.5)) 2>&- && echo "$var"
prompt$ ((var=6/2)) 2>&- && echo "$var"
3
prompt$ ((var=6/0)) 2>&- && echo "$var"

Единственная проблема здесь - ложное срабатывание, если выражение оценивается в 0

((var=0)) 2>&- && echo "$var" # does not print anything

Есть решение этой проблемы, но оно немного длиннее

var=; ((var=0)) 2>&-; [ -n "$var" ] && echo "$var"
...