![마침내](https://linux55.com/image/176128/%EB%A7%88%EC%B9%A8%EB%82%B4.png)
에포크 형식으로 두 날짜의 차이를 구하고 그 숫자를 다시 일수로 변환하려고 합니다.
EXPIRYEPOCH=$(date --date="$EXPIRYDATE" +%s)
TODAYEPOCH=$(date --date="$TODAYSDATE" +%s)
DAYSLEFT=$(expr ($EXPIRYEPOCH - $TODAYEPOCH) / 86400 )
DAYSLEFT
위의 계산은 실패합니다. 반면 아래의 단일 뺄셈 계산은 성공합니다.
DAYSLEFT=$(expr $EXPIRYEPOCH - $TODAYEPOCH)
DAYSLEFT
변수를 설정하는 올바른 형식은 무엇입니까(먼저 뺀 다음 나누기)?
답변1
다음과 같이(더 이상 사용되지 않는 것을 사용하지 마세요 expr
):
dayleft=$(( arithmetic expression ))
부동 소수점 숫자가 필요한 경우세게 때리다, 사용기원전대신에:
dayleft=$(bc -l <<< "scale=2; 100/3")
명시된 바와 같이스티븐 차제라스참고로 , ksh93
및 는 및 내에서 부동 소수점 숫자를 zsh
지원합니다 .yash
$((...))
((...))
expr
고대 쉘 코드에서 수학을 수행하는 데 사용되는 프로그램입니다. bash와 같은 Posix 셸에서는 를 사용합니다 $(( expression ))
. bash, ksh88+, mksh/pdksh 또는 zsh에서는 (( expression ))
또는를 사용할 수도 있습니다.let expression
((...))
표현식이 0이 아니면 종료 상태 0을 반환하거나 표현식이 0이면 1을 반환하는 산술 명령입니다. 부작용(할당)이 필요한 경우 "let"의 동의어로도 사용됩니다. 바라보다http://mywiki.wooledge.org/ArithmeticExpression
$((...))
산술 대체입니다. 산술 연산이 완료되면 전체 내용이 표현식의 값으로 대체됩니다. 바라보다http://mywiki.wooledge.org/ArithmeticExpression
명령 대체: "$(cmd "foo bar")"
"cmd" 명령이 "foo bar" 인수와 함께 실행되고 "$(..)"
출력으로 대체됩니다. 바라보다http://mywiki.wooledge.org/BashFAQ/002그리고http://mywiki.wooledge.org/CommandSubstitution
사용을 피하세요수도시스템 사용을 위해 예약된 변수
마침내
expiryepoch=$(date --date="$expirydate" +%s)
todayepoch=$(date --date="$todaysdate" +%s)
dayleft=$(bc <<< "scale=2; (todayepoch - expiryepoch) / 86400")
답변2
산술 확장의 구문은 입니다 $(( math ))
. 따라서 expr
여기에는 아무것도 필요하지 않습니다. 찾고 있는 것은 다음과 같습니다.
DAYSLEFT=$(( ($EXPIRYEPOCH - $TODAYEPOCH) / 86400 ))
이제 실패하는 이유는 expr
그룹화 표현식을 읽을 수 있는 외부 프로그램이지만 셸에서 괄호를 보호해야 하기 때문입니다. 괄호는 쉘에서 예약된 문자이므로(서브쉘을 열고 닫음) 괄호가 있는 명령문을 전달하려는 경우있는 그대로외부 명령의 경우 대괄호를 이스케이프하고 변수와 연결되지 않도록 대괄호 양쪽에 공백을 남겨 두어야 합니다.
DAYSLEFT=$(expr \( $EXPIRYEPOCH - $TODAYEPOCH \) / 86400 )
또는 다음과 같이 두 가지 표현식으로 나눌 수 있습니다.
$ DAYSLEFT=$( expr $(expr $EXPIRYEPOCH - $TODAYEPOCH) / 86400 )
$ echo $DAYSLEFT
947
또한 연산 결과가 정수가 아닌 경우에는 제대로 작동하지 않습니다.
답변3
대괄호를 이스케이프 처리해야 하며 대괄호와 숫자 사이에 공백이 있어야 합니다. 그렇지 않으면 쉘은 서브쉘이 그곳에서 시작되었다고 생각할 것입니다:
DAYSLEFT=$(expr \( $EXPIRYEPOCH - $TODAYEPOCH \) / 86400 )