쉘 스크립트에서 조건을 사용하는 방법

쉘 스크립트에서 조건을 사용하는 방법

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 작업도 수행할 수 있습니다.

따라서 aOR 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

관련 정보