답변:
let
bash 내장 을 사용하는 다른 방법 :
$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9
노트
따라 @ 스테판 Chazelas가 지적 에, bash
당신이 사용해야 ((...))
이상의 연산을 수행 expr
하거나 let
가독성을 위해.
이식성을 위해 @Bernhard answer$((...))
와 같이 사용하십시오 .
let
. (( a = 3 * (2 + 1) ))
( ksh
ksh, bash 및 zsh에서 제공되며 ksh, bash 및 zsh에서만 사용 가능) 보다 표준 또는 휴대용이 아니며 읽기 어렵거나 인용하기가 쉽지 않습니다. a=$((3 * (2 + 1)))
휴대용으로 사용하십시오 .
((a = 3 * (2 + 1) ))
, 이식성에 대한 대안 a=$((3 * (2 + 1)))
). 따라서 당신이나 당신의 대답에 대한 메모가 아니라 선택된 대답에 반대합니다. 그리고 최고 득점자.
a=1 $[a+2]
또는을 사용했다 a=1 b=2 $[a+b]
. 그 구문을 피해야하는 이유입니까?
대신 산술 확장을 사용할 수 있습니다.
echo "$(( 3 * ( 2 + 1 ) ))"
9
내 개인적인 견해로는을 사용하는 것보다 조금 더 좋아 보입니다 expr
.
에서 man bash
산술 확장 산술 확장을 통해 산술 표현식을 평가하고 결과를 대체 할 수 있습니다. 산술 확장 형식은 다음과 같습니다.
$((expression))
표현식은 큰 따옴표 안에있는 것처럼 처리되지만 괄호 안의 큰 따옴표는 특별히 처리되지 않습니다. 표현식의 모든 토큰은 매개 변수 확장, 문자열 확장, 명령 대체 및 따옴표 제거를 거칩니다. 산술 확장이 중첩 될 수 있습니다.
평가는 산술 평가 아래에 나열된 규칙에 따라 수행됩니다. expression이 유효하지 않으면 bash는 실패를 나타내는 메시지를 인쇄하고 대체가 발생하지 않습니다.
expr
현대 쉘에서 산술에 사용할 이유가 없습니다 .
POSIX는 $((...))
확장 연산자를 정의합니다 . 따라서 모든 POSIX 호환 쉘 ( sh
모든 현대 유닉스 계열, 대시, bash, yash, mksh, zsh, posh, ksh ...)에서 사용할 수 있습니다.
a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))
ksh
또한 let
같은 종류의 산술 표현식이 전달되고 무언가로 확장되지 않고 표현식이 0으로 해석되는지 여부에 따라 종료 상태를 반환 하는 내장 기능을 도입 했습니다 expr
.
if let 'a = 3 * (2 + 1)'; then
echo "$a is non-zero"
fi
그러나 인용문이 어색하고 이해하기 쉽지 않기 때문에 ( expr
물론 같은 정도는 아님) 대체 형식 ksh
도 도입했습니다 ((...))
.
if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
echo "$a is non-zero and 3 > 1"
fi
((a+=2))
훨씬 더 읽기 쉬우 며 대신 사용해야합니다.
let
및 ((...))
에서만 사용할 수 있습니다 ksh
, zsh
그리고 bash
. $((...))
다른 쉘로의 이식성이 필요한 경우 , 구문은 expr
POSIX 이전 Bourne 유사 쉘 (일반적으로 Bourne 쉘 또는 Almquist 쉘의 초기 버전)에만 필요합니다.
Bourne이 아닌 프론트에는 내장 된 산술 연산자가있는 몇 개의 쉘이 있습니다.
csh
/ tcsh
(실제로 산술 평가 기능이 내장 된 최초의 유닉스 쉘) :
@ a = 3 * (2 + 1)
akanga
(기준 rc
)
a = $:'3 * (2 + 1)'
1989 년에 유즈넷에 게시 된 Almquist 쉘의 원래 버전은 기본적으로 expr
내장되어 test
있었지만 (실제로 병합 됨 ) 나중에 제거되었습니다.
: $((a = a*2))
?
$((...))
zsh, ksh93 또는 yash와 같은 부동 소수점을 지원하는 셸이 필요합니다 .
expr
외부 명령이며 특수 쉘 구문이 아닙니다. 따라서 expr
쉘 특수 문자를 보려면 인용 부호를 사용하여 쉘 구문 분석으로부터 보호해야합니다. 또한 expr
각 숫자와 연산자를 별도의 매개 변수로 전달해야합니다. 그러므로:
expr 3 \* \( 2 + 1 \)
1970 년대 또는 1980 년대의 골동품 유닉스 시스템을 사용하지 않는 한, 사용할 이유가 거의 없습니다 expr
. 예전에는 셸에 산술을 수행하는 기본 제공 방법이 없었으므로 expr
대신 유틸리티 를 호출해야 했습니다. 모든 POSIX 쉘에는 산술 확장 구문을 통해 내장 된 산술이 있습니다.
echo "$((3 * (2 + 1)))"
구조 $((…))
는 산술 연산 결과 (10 진수로 표시됨)로 확장됩니다. 대부분의 셸과 마찬가지로 Bash는 정수 산술 모듈로 2 64 (또는 이전 버전의 bash 및 32 비트 시스템의 다른 셸의 경우 모듈로 2 32) 만 지원합니다 .
배시는 할당을 수행하거나 표현식이 0인지 여부를 테스트하지만 결과에 신경 쓰지 않을 때 추가 편의 구문을 제공합니다 . 이 구조는 ksh와 zsh에도 존재하지만 일반 sh에는 존재하지 않습니다.
((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then …
정수 산술 외에도 expr
몇 가지 문자열 조작 기능을 제공합니다. 이것들도 POSIX 쉘의 기능에 의해 제외되고, 하나를 제외하고 : expr STRING : REGEXP
문자열이 지정된 정규 표현식과 일치하는지 테스트합니다. 는 POSIX 쉘은 외부 도구없이이 작업을 수행 할 수 있지만, bash는 함께 할 수 [[ STRING =~ REGEXP ]]
의 (a와 다른 정규 표현식 구문 - expr
고전적인 도구입니다 BRE를 사용 배쉬는 ERE를 사용합니다).
20 년 된 시스템에서 실행되는 스크립트를 유지 관리하지 않는 한 기존 스크립트를 알 필요는 없습니다 expr
. 쉘 산술을 사용하십시오.
expr foo : '\(.\)'
텍스트 추출도 수행합니다. bash
의는 BASH_REMATCH
비슷한을 달성한다. 또한 POSIX [
가하지 않는 문자열 비교를 수행합니다 (물론 사용 방법을 상상할 수 sort
는 있음).
따옴표와 함께 괄호를 사용하십시오.
expr 3 '*' '(' 2 '+' 1 ')'
9
따옴표는 bash가 괄호를 bash 구문으로 해석하지 못하게합니다.
expr
명령 행 의 토큰 이 공백으로 분리되어야한다는 것입니다. 그래서; 예를 들어 expr 3 "*" "(2" "+" "1)"
작동하지 않습니다 . (또한 BTW, 당신은 아마 인용 할 필요가 없습니다 +
.)
while
and와 같은 키워드가 아니며 [[
구문입니다. 키워드 인 경우 명령 인수에서 해석되지 않습니다. bash가 구문 분석하지 않고 대신 문자열 리터럴을 볼 수 있도록 따옴표가 필요합니다.