0으로 나누기를 무시하거나 캡처합니다.

0으로 나누기를 무시하거나 캡처합니다.

Bash에서 0으로 나누기 오류를 무시하는 방법은 무엇입니까?

예 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에는 0으로 나누기를 잡을 수 있는 방법이 없으며 ash, ksh93, pdksh 또는 zsh도 마찬가지입니다. 0으로 나누기를 잡는 유일한 방법은 나누기가 발생하기 전에 감지하거나(나누기를 수행하기 전에 각 분모를 확인) 서브쉘에서 나누기를 수행하는 것입니다.

서브쉘에서 산술 연산을 수행하는 경우 서브쉘의 종료 상태를 사용하여 오류가 발생했는지 알 수 있습니다(0 또는 기타 오류로 나누기).

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)에서도 작동할 것입니다.

관련 정보