SOFTMOA TECHNOLOGY

Bash 08과 09 계산에서 value too great for base 오류 해결 방법

소프트모아가 정리한 기술 기록입니다.

Contents
작성일 2026. 10. 25.

Bash 스크립트가 월 값 07까지는 동작하다가 08·09에서 value too great for base로 멈춘다면, 앞자리 0 때문에 숫자를 8진수로 해석하는지 확인해야 합니다. 입력 형식을 먼저 검사하고 10#으로 10진수 변환을 지정하면 됩니다.[1][2] 월을 읽는 배치나 파일명 생성 스크립트에 적용할 수 있는 방법입니다. 소프트모아가 오류 재현과 잘못된 입력을 거부하는 예제를 정리했습니다.

08은 오류인데 010은 조용히 다른 값이 됩니다

Bash 산술식은 선행 0이 붙은 정수 상수를 8진수로 취급합니다. 8진수에는 숫자 8과 9가 없어서 08·09가 실패합니다.[1] 아래 명령은 현재 셸을 종료하지 않도록 별도의 Bash에서 오류를 재현합니다.

/bin/bash --version
/bin/bash -c 'month=08; printf "%s\n" "$((month + 1))"'

macOS ARM64의 Bash 3.2.57에서 두 번째 명령은 표준 출력 없이 오류 메시지를 내고 종료 코드 1로 끝났습니다. 문법과 제한 조건은 Bash 5.3 공식 매뉴얼과 대조했습니다.[1] Linux 서버에서 직접 실행한 결과는 아니며, 서버에서도 먼저 Bash 버전을 확인해야 합니다.

/bin/bash: 08: value too great for base (error token is "08")

오류가 없다고 값까지 맞는 것은 아닙니다. 다음 명령의 출력은 8 10입니다. 010은 8진수 10으로, 10#010은 10진수 10으로 계산했습니다. 07처럼 두 진법에서 값이 같은 입력만 시험하면 차이가 드러나지 않습니다.[1][2]

/bin/bash -c 'printf "%s %s\n" "$((010))" "$((10#010))"'

두 자리 월 입력만 받은 뒤 변환합니다

여기서는 입력 계약을 문자열 01~12로 한정합니다. 8 한 자리, 부호, 공백은 자동 보정하지 않고 거부합니다. 시스템마다 허용 형식이 다르므로 이 정책은 그대로 적용할 규정이 아니라 예제의 조건입니다. 다음 내용을 month-check.sh로 저장합니다.

#!/usr/bin/env bash
LC_ALL=C
parse_month() {
  local raw=$1 month
  if [[ ! $raw =~ ^[0-9]{2}$ ]]; then
    printf 'INVALID format: [%s]\n' "$raw" >&2
    return 2
  fi
  month=$((10#$raw))
  if (( month < 1 || month > 12 )); then
    printf 'INVALID range: [%s]\n' "$raw" >&2
    return 2
  fi
  printf '%d\n' "$month"
}
failed=0
for raw in 07 08 09 00 13 x8 8 '' '1+1'; do
  if month=$(parse_month "$raw" 2>/dev/null); then
    printf '[%s] => %s\n' "$raw" "$month"
  else
    rc=$?
    printf '[%s] => REJECT (%d)\n' "$raw" "$rc"
    failed=2
  fi
done
exit "$failed"

정규식의 시작·끝 표시로 문자열 전체가 숫자 두 자리인지 확인한 다음 산술식에 넣습니다. Bash의 =~는 확장 정규식을 사용하며, 패턴 전체를 따옴표로 감싸면 리터럴로 해석하므로 위 코드의 정규식은 그대로 둡니다.[1] 형식 통과와 유효한 월인지는 별개입니다. 00과 13은 변환할 수 있어도 1~12 범위 밖이어서 거부합니다.

10#은 진법 지정이지 입력 검증기가 아닙니다. 외부 문자열을 검사 없이 산술식에 넣는 방식은 피해야 합니다.[3] 이 예제는 부호 없는 두 자리 숫자만 허용해 긴 정수나 수식이 들어가는 경로를 먼저 막습니다. 주민번호·상품코드처럼 선행 0 자체가 의미인 값은 숫자로 바꾸지 말고 문자열로 유지해야 합니다.

변환 결과와 실패 상태를 함께 확인합니다

/bin/bash -n month-check.sh
/bin/bash month-check.sh
printf 'exit=%s\n' "$?"

문법 검사는 출력 없이 종료 코드 0이었습니다. 실행 결과는 아래와 같고, 이어서 exit=2가 출력됩니다. 일부 입력을 의도적으로 거부하도록 만든 시험이므로 이 종료 코드가 정상적인 검증 결과입니다.

[07] => 7
[08] => 8
[09] => 9
[00] => REJECT (2)
[13] => REJECT (2)
[x8] => REJECT (2)
[8] => REJECT (2)
[] => REJECT (2)
[1+1] => REJECT (2)

입력 9개 중 3개만 변환되고 6개는 거부됐습니다. 함수는 거부 사유를 표준 오류로 보내지만, 시험 반복문은 이를 숨기고 요약만 출력합니다. 실제 입력을 조사할 때는 2>/dev/null을 제거해 형식 오류와 범위 오류를 구분합니다. 마지막 exit은 거부가 하나라도 있으면 2를 반환합니다. 마지막 출력 명령이 성공했다는 이유로 배치 전체가 성공 처리되지 않게 한 것입니다.

  • 코드는 Bash용입니다. sh month-check.sh로 바꾸지 말고 위 실행 명령을 사용합니다.[1]
  • 계산한 8을 화면에 08로 표시하려면 변환을 통과한 값에 printf '%02d\n' "$month"를 적용합니다. 표시 형식과 산술용 숫자를 나눕니다.[1]
  • 검사는 월 하나만 다룹니다. 2월 30일, 윤년, 12월의 다음 달과 연도 변경은 검증하지 않습니다. 실제 날짜 계산은 별도로 처리해야 합니다.

이 예제는 메모리 안에서 입력을 검사하고 출력할 뿐 파일 이동이나 데이터 등록을 수행하지 않습니다. 변환된 값이 나왔다고 후속 작업까지 완료된 것은 아닙니다. 운영 배치에 연결할 때는 거부된 입력을 기록하고 실제 처리 결과도 따로 확인해야 합니다.

참고 문서

소프트모아는 해당 시스템을 구축합니다. 문의하기

Share this

OS

Have a questions?

견적 및 기술문의

mobile : 010-7931-4813

Contact Form