두 개의 문자열이 있습니다
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
다음과 같은 일이 발생합니다.
- 변수의 값을 가져옵니다. 결과는 문자열입니다.
- 값을 공백으로 구분된 청크로 분할합니다. 결과는 문자열 목록입니다.
- 목록의 각 요소를 와일드카드 패턴으로 해석합니다.와일드카드. 파일과 일치하면 해당 요소를 일치하는 목록으로 바꿉니다. 일치하는 파일이 없으면 요소가 유지됩니다.
예를 들어 값에 단어가 포함된 변수는 *
현재 디렉터리에 있는 파일 이름 목록으로 대체됩니다.
일반적으로 변수 대체 및 명령 대체는 항상 큰따옴표( "$stuff"
, ) 로 묶습니다 "`stuff`"
. 바라보다공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?따옴표가 필요한 이유를 알고 이해하는 경우에만 따옴표를 생략하십시오.
expr
이 경우 연산자와 피연산자가 별도의 매개변수에 있어야 하므로 2단계(분할)를 수행해야 합니다 . 그러나 3단계(각 단어를 파일 이름 와일드카드 패턴으로 처리)는 발생하지 않아야 합니다. 와일드카드를 꺼서 이 작업을 수행할 수 있습니다.
result=`set -f; expr $str2`
ksh 또는 bash에서는 문자열 대신 배열을 사용합니다. 하지만 해당 쉘에서는 expr
.
스크립트를 고대 Bourne 쉘로 이식해야 하는 경우가 아니면 이를 사용할 필요가 없습니다 expr
. 산술 표현식은 표준 POSIX 기능입니다.
result=$(($str2))
1 구분자는 IFS
변수를 통해 구성할 수 있습니다.