DASH 스크립트 오류: 변수를 올바르게 설정하는 방법을 모르는 것 같습니다.

DASH 스크립트 오류: 변수를 올바르게 설정하는 방법을 모르는 것 같습니다.
#!/bin/sh

export $REG=0x000000
export $DONE=0x4A9FFF

while $REG -le $DONE
   do  
    (($REG+1))
    printf 'wm8280_reg get 0x'$REG'\r\n' 
    sleep 1 
   done

이로 인해 오류가 발생합니다.

./wm8280_reg_get1.sh: line 3: export: `=000000': not a valid identifier
./wm8280_reg_get1.sh: line 4: export: `=4A9FFF': not a valid identifier
./wm8280_reg_get1.sh: line 6: -le: command not found

나는 그것이 "작거나 같음"에 dash대한 것이라고 확신 하지만 분명히 내가 틀렸습니다. -le또한 내 변수가 왜 잘못된지 잘 모르겠습니다. 내가 뭘 잘못했나요?

답변1

sh최신 버전을 포함하여 모든 규격 구현에서 작동해야 하는 표준(POSIX) 구문은 다음 dash과 같습니다.

#!/bin/sh -

reg=0x000000
done=0x4A9FFF

while [ "$((reg))" -le "$((done))" ]; do
  reg=$((reg + 1))
  printf 'wm8280_reg get 0x%06X\r\n' "$reg"
  sleep 1 
done

dash0.5.5(2009) 이전 버전 으로 마이그레이션해야 하는 경우 다음이 필요합니다.

#!/bin/sh -

reg=0x000000
done=0x4A9FFF

while [ "$(($reg))" -le "$(($done))" ]; do
  reg=$(($reg + 1))
  printf 'wm8280_reg get 0x%06X\r\n' "$reg"
  sleep 1 
done

POSIX 사양은 확장 방법(본문에서는 아직 명확하지 않지만 최소한 메일링 리스트와 적합성 테스트 제품군에서는 Open Group의 입장이 명확해졌습니다)과 기본 변수 사용에 $((reg))대해 과거에는 그다지 명확하지 않았습니다. dash산술 표현식은 지원되지 않지만( no $) 사양은 "$(($ver))항상 더 명확합니다.

$reg첫 번째 호출 이후에는 10진수로 표시 되므로 reg=$(($reg + 1))처음에는 변수를 10진수로 변환할 수도 있습니다. 또한 0x1 ~ 0x4AA000(56일 후)의 숫자를 인쇄한다는 점에 유의하세요. 보다 전통적인(그리고 제 생각에는 더 명확한) 작성 방법은 다음과 같습니다.

#!/bin/sh -

reg=$((0x000001))  done=$((0x4AA000))

while [ "$reg" -le "$done" ]; do
  printf 'wm8280_reg get 0x%06X\r\n' "$reg"
  sleep 1 
  reg=$(($reg + 1))
done

또한 매초마다 정확히 한 줄을 인쇄할 것으로 기대하지 마십시오. 이러한 명령을 실행하는 데 걸리는 시간으로 인해 편향이 발생합니다.

세부 사항:

  • export실행하려는 명령의 환경으로 변수를 내보내면 됩니다. 여기서는 사용해도 소용이 없습니다. 이 변수는 여기서만 전달하는 데 사용됩니다.명령의 매개변수로.
  • $값을 확장하려는 경우 앞에 변수를 넣을 수 있습니다. export $reg=0x000000하나를 실행합니다 export value-of-reg=0x000000.
  • while그 뒤에는 실행할 명령(또는 명령 목록)이 오고 해당 종료 상태가 루프 조건을 결정합니다. 여기에는 [정수 비교와 같은 다양한 테스트를 수행하는 데 사용할 수 있는 명령(대부분의 쉘에 내장되어 있음)이 필요합니다 .
  • 그러나 이러한 산술 비교 연산자는 [10진수 정수 상수만 지원하므로 이를 10진수로 변환하기 위해 쉘 산술 확장(16진수 지원)을 사용합니다.
  • 화장품: 관례에 따라 우리는 일반적으로 환경 변수나 전역 변수가 있어야 하는 변수에 대해 모두 대문자 변수 이름을 사용합니다.범위예를 들어, 함수를 사용하는 복잡한 스크립트에서.

답변2

이 예

#!/bin/sh

export $REG=0x000000
export $DONE=0x4A9FFF

while $REG -le $DONE
   do  
    (($REG+1))
    printf 'wm8280_reg get 0x'$REG'\r\n' 
    sleep 1 
   done

변경해야 할 사항:

  • 이 두 줄은 변수 앞에 붙으면 export안 됩니다 .$
  • 표현식 주위에 및 사용 [(또는 이전)]$REG -le $DONEtest
  • 변수를 참조할 때읽다, 표현식에 표시된 대로입니다.
  • printf문자열 연결이 아닌 서식 지정 용

그래서 당신은 다음과 같은 것을 가질 것입니다

#!/bin/sh

export REG=0x000000
export DONE=0x4A9FFF

while [ "$REG" -le "$DONE" ]
   do  
    (($REG+1))
    printf 'wm8280_reg get 0x%s\r\n' "$REG" 
    sleep 1 
   done

이 줄

    while [ "$REG" -le "$DONE" ]

다음과 같이 쓸 수도 있습니다.

    while test "$REG" -le "$DONE"

(둘 다 합법적입니다).

dash의 매뉴얼 페이지를 빠르게 읽어보면 대시가 16진수 상수를 지원한다는 내용이 나와 있지 않습니다. 소수 값을 사용하도록 이러한 내보내기를 변경해야 할 수도 있습니다. 예를 들어,

export REG=0
export DONE=489063

%06X그런 다음 대신 printf를 사용하여 %s값을 16진수로 인쇄할 수 있습니다.

cuonglm의 제안을 사용하면 다음을 사용할 수 있습니다.

while [ "$((REG))" -le "$((DONE))" ]  

그리고

REG=$(($((REG))+1))

POSIX 쉘을 참조2.6.4 산술 확장:

10진수 상수, 8진수 상수만16진수- ISO C 표준 6.4.4.1항에 명시된 상수는 상수로 인식되어야 합니다.

그러나 테스트스프린트printfDebian 7 및 8에서는 16진수로 가정할 때 결과가 10진수이기 때문에 증가 표현식이 OP가 의도한 대로 작동하지 않을 수 있습니다 . 또한 REG=((REG+1))이 대시 버전에서는 작동하지 않습니다. (물론 bash는 다른 이야기입니다).

답변3

좋아요, 여러분의 의견에 감사드립니다. 최종 스크립트는 다음과 같습니다.

#!/bin/sh

export REG=0
export DONE=4890632

while [ "$((REG))" -le "$((DONE))" ]
   do  
    wm8280_reg get $REG >> "wm_reg_dump.txt"
    REG=$(($((REG))+1))
   done

DASH에서 실행되며 원하는 출력을 갖습니다. 물론 코드를 실행하는 데 8시간이 걸리지만, 설정하고 잊어버리세요 :)

관련 정보