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