expr 사용 중 문제

expr 사용 중 문제

두 개의 문자열이 있습니다

str1="( 1 + 2 + 3 + 4 + 5 ) / 3 + 5"

그리고

str2="( 1 + 2 + 3 + 4 + 5 ) / 3 + 5 * 2"

주문하다

result=` expr $str1`

동안 올바른 값을 반환합니다.

result=` expr $str2`

반품expr: syntax error

답변1

다음은 잘못된 결과를 생성합니다.

str2="( 1 + 2 + 3 + 4 + 5 ) / 3 + 5 * 2"
expr $str2

문제는 쉘이 *와일드카드 파일 glob을 생각하고 이를 현재 디렉토리의 파일 목록으로 대체한다는 것입니다. 당신이 원하는 것이 아닌가요?

expr고대입니다. 보다 현대적인 해결책은 쉘 $((...))형식의 산술을 사용하는 것입니다.

$ str2="( 1 + 2 + 3 + 4 + 5 ) / 3 + 5 * 2"
$ echo "$((str2))"
15

쉘은 정수 산술만 수행합니다. 부동 소수점의 정확한 결과를 정말로 원한다면(여기서도 마찬가지임) 다음을 사용하십시오 bc.

$ echo "$str2" | bc -l
15.00000000000000000000

$str2쉘 헛소리를 방지하려면 큰따옴표를 사용하십시오 .

답변2

큰따옴표 외부에서 변수를 확장하면( 에 표시된 대로) expr $str2다음과 같은 일이 발생합니다.

  1. 변수의 값을 가져옵니다. 결과는 문자열입니다.
  2. 값을 공백으로 구분된 청크로 분할합니다. 결과는 문자열 목록입니다.
  3. 목록의 각 요소를 와일드카드 패턴으로 해석합니다.와일드카드. 파일과 일치하면 해당 요소를 일치하는 목록으로 바꿉니다. 일치하는 파일이 없으면 요소가 유지됩니다.

예를 들어 값에 단어가 포함된 변수는 *현재 디렉터리에 있는 파일 이름 목록으로 대체됩니다.

일반적으로 변수 대체 및 명령 대체는 항상 큰따옴표( "$stuff", ) 로 묶습니다 "`stuff`". 바라보다공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?따옴표가 필요한 이유를 알고 이해하는 경우에만 따옴표를 생략하십시오.

expr이 경우 연산자와 피연산자가 별도의 매개변수에 있어야 하므로 2단계(분할)를 수행해야 합니다 . 그러나 3단계(각 단어를 파일 이름 와일드카드 패턴으로 처리)는 발생하지 않아야 합니다. 와일드카드를 꺼서 이 작업을 수행할 수 있습니다.

result=`set -f; expr $str2`

ksh 또는 bash에서는 문자열 대신 배열을 사용합니다. 하지만 해당 쉘에서는 expr.

스크립트를 고대 Bourne 쉘로 이식해야 하는 경우가 아니면 이를 사용할 필요가 없습니다 expr. 산술 표현식은 표준 POSIX 기능입니다.

result=$(($str2))

1 구분자는 IFS변수를 통해 구성할 수 있습니다.

관련 정보