if
스크립트에 진술이 있습니다 .
다음과 같습니다.
if [ "$a" != "0" -a "$b" != "100" ]; then
#some commands here
내가 올바르게 기억한다면 두 조건이 모두 참이면 위 줄이 작동합니다.
이제 어떻게 테스트하나요?누구나둘 다 참이 되기 전에 하나 또는 두 조건을 모두 실행합니까 some commands
?
답변1
표준(POSIX sh 및 유틸리티)에서 이를 지정하는 명확한 방법은 다음과 같습니다.
끈비교하다:
if [ "$a" != 0 ] || [ "$b" != 100 ]; then...
십진수비교하십시오(0100은 100이지만 선행 공백이 무시되는지 여부는 구현에 따라 다릅니다).
if [ "$a" -ne 0 ] || [ "$b" -ne 100 ]; then...
정수비교하십시오(0x64, 0144는 100입니다(일부 쉘은 8진수에 대해 POSIX 모드를 활성화해야 함).
RANDOM
따라서 쉘 100.0, 1e2, 50+50...에 따르면 (0.003%의 경우)...):if [ "$((a != 0 || b != 100))" -ne 0 ]; then...
그러나 변수의 내용으로 인해 구문 오류로 인해 산술 확장이 실패하면 셸이 중단되므로 이 문제를 해결하려면 하위 셸에서 실행해야 할 수도 있습니다.
if ([ "$((a != 0 || b != 100))" -ne 0 ]); then
변수의 내용을 제어할 수 없는 경우 이 형식을 사용하면 안 됩니다.하나임의 명령 실행 취약점수많은 껍질 중에서(
bash
,ksh
,zsh
) (예:$a
와 같은 값x[$(reboot)]
).
어떤 것을 선택하느냐는 변수의 내용과 원하는 내용에 따라 달라집니다. 표준 형식의 10진수 정수가 포함되어 있다는 것을 알고 있는 경우 3개 모두 동일합니다.
그럼에도 불구하고 -a
/ -o
test
연산자 를 사용하지 마십시오.일반적으로 더 이상 사용되지 않으며 신뢰할 수 없음(변수의 내용을 제어할 수 있는 경우에는 여기가 아닙니다.)
답변2
모호함을 피하기 위해 산술 평가와 괄호를 사용하십시오.
if (( ($a != 0) || ($b != 100) )); then
# some commands
또는 문자열도 처리하려면 [[
.
답변3
[ "$((a||b^100))" -eq 1 ] && some commands
쉘의 수학 확장은 표현식을 1(true) 또는 0(false)으로 평가하여 부울 &&
AND ||
OR 및 NOT 조건을 처리합니다. !
또한 비트 &
AND |
OR 및 ^
XOR 연산자를 처리하지만 비트 표현식이 여기에서와 같이 부울 평가의 필드로 사용될 수 있지만 반드시 결과가 0 또는 1이 되는 것은 아닙니다. 흥미롭게도 쉘은 회전 ~
과 <<
왼쪽 및 오른쪽 >>
SHIFT 작업도 수행할 수 있습니다.
따라서 a
OR b^100
가 true이면 확장은 1로 평가되어 비교 -eq
[
테스트 와 일치 ]
하고 쉘은 나머지 평가를 계속합니다 && some commands
.
정수를 함께 묶는 것보다 이런 방식으로 정수를 평가/비교하는 것이 더 쉬운 경우가 많습니다.
...그리고 바이너리
-a
프라이머리-o
및 연산자는 더 이상 사용되지 않는 것으로 표시(
되었습니다)
.(이를 사용하는 많은 표현식은 평가되는 특정 표현식에 따라 구문에 의해 모호하게 정의됩니다.)
(^ test
사양에서 직접 인용)
이것이 성공하더라도 정식으로 가입하기 전에 갈 수 있는 제한은 4개입니다.명시되지 않은지역.
과거에는 다음과 같은 추상화를 적용하는 것이 유용하다는 것을 자주 알았습니다.
math(){ return "$((!($1)))"; }
...다음과 같이 사용할 수 있습니다
math 'a||b^100' && some commands
비록 이것이 제가 생각한 것과는 다르지만 실제로 POSIX 사양에서 얻었습니다.XRAT 근본적인부분:
...[i]는
test
주문이 다음과 같이 결론을 내립니다.([
)이는 대부분의 관계형 산술 테스트에 충분하며, 셸에서 복잡한 관계식을 포함하는 테스트는 드물지만"$(())"
자체 값을 테스트하여 만족할 수 있습니다. 예를 들어:
# a complicated relational expression
while [ "$(( (($x + $y)/($a * $b)) < ($foo*$bar) ))" -ne 0 ]
...또는 더 좋은 점은 복잡한 관계 표현식이 많은 희귀한 스크립트가 그러한 함수를 정의할 수 있다는 것입니다...
val() { return "$((!$1))"; }
"
( 위에 인용문을 추가했지만 . 저 사람들은 무슨 문제가 있는 걸까요?)
답변4
위에서 본 것보다 더 간단한 답변입니다.
if [ "$a" != "0" -o "$b" != "100" ]; then